Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Expand const impls of PartialEq, Eq, PartialOrd and Ord #146097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
npmccallum wants to merge 7 commits into rust-lang:master
base: master
Choose a base branch
Loading
from npmccallum:const_cmp

Conversation

Copy link
Contributor

@npmccallum npmccallum commented Sep 1, 2025
edited
Loading

Related to: #143800
Requires (includes): #146088
Requires (not included): #146089

jasper310899 reacted with hooray emoji
Copy link
Collaborator

rustbot commented Sep 1, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 1, 2025
Copy link
Collaborator

rustbot commented Sep 1, 2025

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This comment has been minimized.

Copy link
Contributor

oli-obk commented Sep 1, 2025

Oh no. What did I do with rustfmt. const pub trait Foo is funny

Comment on lines 220 to 211
default fn chaining_le(left: &[Self], right: &[Self]) -> ControlFlow<bool> {
chaining_impl(left, right, PartialOrd::__chaining_le, usize::__chaining_le)
let l = cmp::min(left.len(), right.len());

// Slice to the loop iteration range to enable bound check
// elimination in the compiler
let lhs = &left[..l];
let rhs = &right[..l];

let mut i = 0;
while i < l {
match PartialOrd::__chaining_le(&lhs[i], &rhs[i]) {
ControlFlow::Continue(()) => {}
ControlFlow::Break(b) => return ControlFlow::Break(b),
}
i += 1;
}

usize::__chaining_le(&left.len(), &right.len())
}
Copy link
Contributor

@tgross35 tgross35 Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't all of this wait for const iterators? I don't know that the motivation is strong enough to justify switching to less maintainable code.

Copy link
Contributor

@clarfonthey clarfonthey Sep 2, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, main issue with const iterators is that a large portion of use cases require const closures, and that's probably going to take a pretty long while. It's entirely feasible that const traits get stabilised before const closures are viable.

Plus, there's just going to have to be a massive audit of const code once const iterators are usable anyway, so, it doesn't seem that bad to add more while loops for usefully-const code. But I think we definitely should be marking all of them for future updating.

Copy link
Contributor

@tgross35 tgross35 Sep 2, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can buy the fact that we may want const trait impls before we have const closures, and on a case-by-case basis we occasionally do iterator->indexing conversions to make const fn impls work. And the changes in this specific PR aren't that bad. But the net effect of doing this across the codebase adds up, and that part doesn't thrill me if the plan is just to rewrite it in the not-so-distant future. (I realize we need a real policy here, I've started writing one up.)

It's totally fine to say that the motivation is stronger than for a one-off impl because it unblocks a lot. But isn't SliceChain only used for a specialization anyway?

clarfonthey reacted with thumbs up emoji
Copy link
Contributor

@clarfonthey clarfonthey Sep 2, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main issue with specialisation impls not being made const is they can implicitly mess with the non-const impls if we're not careful: some traits have const bounds instead of [const] bounds and I'm not sure every specialization impl has an associated codegen test. (This is a valid reason to put more scrutiny on these implementations! I just wanted to point out how subtle the changes can be.)

Besides, they exist to speed things up for a reason, and considering just how much slower miri can be, this could probably substantially affect compile times using this code if not done carefully.

Definitely looking forward to whatever you write up for a policy, though. I think most of the code should be detectable with clippy lints that currently don't fire in const code, but it is a fair bit concerning nonetheless.

Copy link
Contributor Author

@npmccallum npmccallum Sep 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tgross35 I agree with you that it isn't that great. I solved this by removing all the inlining in favor of regular const functions. See the latest push.

This comment has been minimized.

This comment has been minimized.

Also constify the impls of basic types.
One potentially controversial part of this change is making Eq, a
marker trait, const. I chose to do this ease user adoption.
Otherwise, code which already has an Eq bound and uses it to
proxy a PartialEq bound would need to add a separate bound. This
would cause a litering of bounds in downstream types.
Copy link
Collaborator

rustbot commented Sep 3, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Copy link
Collaborator

The job tidy failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
[TIMING:end] tool::Tidy { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu } -- 0.000
fmt check
Diff in /checkout/library/core/src/cmp.rs:336:
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Eq"]
 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
-pub const trait Eq: [const] PartialEq<Self> + PointeeSized {
+const pub trait Eq: [const] PartialEq<Self> + PointeeSized {
 // this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a
 // type implements `Eq` itself. The current deriving infrastructure means doing this assertion
 // without using a method on this trait is nearly impossible.
Diff in /checkout/library/core/src/cmp.rs:963:
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Ord"]
 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
-pub const trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized {
+const pub trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized {
 /// This method returns an [`Ordering`] between `self` and `other`.
 ///
 /// By convention, `self.cmp(&other)` returns the ordering matching the expression
Diff in /checkout/library/core/src/cmp.rs:1348:
 #[rustc_diagnostic_item = "PartialOrd"]
 #[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this
 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
-pub const trait PartialOrd<Rhs: PointeeSized = Self>:
+const pub trait PartialOrd<Rhs: PointeeSized = Self>:
 [const] PartialEq<Rhs> + PointeeSized
 {
 /// This method returns an ordering between `self` and `other` values if one exists.
fmt: checked 6354 files
Bootstrap failed while executing `test src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck`
Build completed unsuccessfully in 0:00:48

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@tgross35 tgross35 tgross35 left review comments

+1 more reviewer

@clarfonthey clarfonthey clarfonthey left review comments

Reviewers whose approvals may not affect merge requirements
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /