Skip to content

Constify Eq, Ord, PartialOrd #144847

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
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Constify Eq, Ord, PartialOrd #144847

wants to merge 1 commit into from

Conversation

Randl
Copy link
Contributor

@Randl Randl commented Aug 3, 2025

Adds #[const_trait] and impls for Eq, Ord, PartialOrd. Impl for some other traits (e.g., slices and arrays) are blocked mainly on const closures (#106003).
For TypeId Ord we need const pointer comparison (#53020)
Tracking issue #143800

@rustbot
Copy link
Collaborator

rustbot commented Aug 3, 2025

r? @ibraheemdev

rustbot has assigned @ibraheemdev.
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-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 3, 2025
@rustbot
Copy link
Collaborator

rustbot commented Aug 3, 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

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@compiler-errors
Copy link
Member

Squash this into one commit please

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 3, 2025
@rustbot
Copy link
Collaborator

rustbot commented Aug 3, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@Randl
Copy link
Contributor Author

Randl commented Aug 3, 2025

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 3, 2025
@ShoyuVanilla
Copy link
Member

Not a review but just a question as I don't know the contexts very well 😅
I guess PartialEq and Eq could be const impl'd on tuples as well?

@rust-log-analyzer

This comment has been minimized.

@Randl
Copy link
Contributor Author

Randl commented Aug 8, 2025

Fair enough, I've added impl const for tuples

@compiler-errors
Copy link
Member

Sorry for taking a long time to review this. I'm actually somewhat uncomfortable by the scope of this PR. Could you please limit the number of types that this adds const impls for to just types that seem relevant for const programming?

Specifically, things like:

#[derive(Copy, Debug)]
#[derive_const(Clone, PartialEq, Eq)]
pub struct AllocError;

Don't seem really relevant here. I think this constification could probably just stick to constifying some impls for built-in types and other important types, and not just try to constify everything that can be constified in the standard library.

Also, since this adds new bounds to things, let's run a perf test.

@bors2 try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Aug 14, 2025
Constify Eq, Ord, PartialOrd
@compiler-errors
Copy link
Member

@rustbot author

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Aug 14, 2025
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 15, 2025
pub trait Eq: PartialEq<Self> + PointeeSized {
#[const_trait]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
pub trait Eq: [const] PartialEq<Self> + PointeeSized {
Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW, when I was working on this before I decided that I should do #144289 first, I figured that Eq actually shouldn't be const even though it would make bounds easier because ultimately, for a majority of users, the difference between const Eq and Eq is negligible since Eq itself doesn't contain any methods.

I guess it's a bit debatable, but I figured it wasn't worth distinguishing whether the Eq impl was const or not, just the PartialEq impl. It means that a lot of things will need Eq + [const] PartialEq instead of [const] Eq, but I figured that it would be better to make the former canonical than risk the former actually only being what's required despite the latter being easier to type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

risk the former actually only being what's required despite the latter

But the former implies the latter, right? There can't be Eq + [const] PartialEq that is not practically [const] Eq. So the difference is semantic and syntactic. From a semantic point of view, I see advantages of both approaches. x: [const] Eq makes sense because it means that we want to use Eq trait in a const context. On the other hand, if we interpret [const] trait as "all the methods of trait are const callable," then any trait without methods shouldn't be const. From a syntactic point of view, I think [const] Eq is clearly more convenient. We already have to sprinkle [const] Destruct all over the place; having to be even more verbose is a disadvantage in my opinion. I guess that there should be some decision regarding the best practice for no-method traits.

cc @oli-obk @RalfJung

Copy link
Contributor

Choose a reason for hiding this comment

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

The issue is that you can't use Eq in const contexts: Eq is just a marker, and PartialEq is what you're actually using.

Copy link
Contributor Author

@Randl Randl Aug 15, 2025

Choose a reason for hiding this comment

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

Well, at the risk of repeating myself, that depends on how you interpret [const] trait. If [const] trait means that "all methods of the trait are const callable" then you're 100% right. If it means "trait defines the functionality a particular type has that can be used in const context", then [const] Eq makes sense: it defines functionality that can be used in const (via methods of PartialEq, just like non-const version). This is purely semantic distinction.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not involved much with const traits, Cc @fee1-dead

Copy link
Member

Choose a reason for hiding this comment

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

T: [const] Eq is not so different from T: Eq + [const] PartialEq if everyone writes impl const Eq for MyType. On one hand, you can think of it as a silly additional requirement. There's no difference of impl const Eq from impl Eq if you know MyType implements const PartialEq.

On the other hand, it also seems silly to only allow derive_const for PartialEq and not Eq. It isn't too much to ask people to implement [const] Eq if they call a function that requires total equality in compile time.

I don't have a preference one way or the other.

@fee1-dead
Copy link
Member

#143949 also caused some minor perf regressions, but so far nobody from wg-const-eval has commented on whether this is considered acceptable or not. Right now my understanding is that the goal is to constify everything, but there may need to be some changes with consteval since my suspicion is that the built-in stuff to allow these operators to work even without trait impls on primitives may now be slower with the const trait impls present and enabled.

Note that regressions on the PR you linked was ultimately triaged at the rollup.

Those negative perf results are due to making built-in traits const, which then increases the times where we have to check const conditions of traits, find implied predicates (super traits), etc. They're pretty much unavoidable, there's nothing much we can do, and we'll have to stick with it if we want libstd constified.

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

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

Some leftover syntax, otherwise lgtm

@rustbot
Copy link
Collaborator

rustbot commented Aug 16, 2025

This PR was rebased onto a different master commit! Check out the changes with our range-diff.

@oli-obk oli-obk assigned oli-obk and unassigned compiler-errors Aug 16, 2025
@oli-obk
Copy link
Contributor

oli-obk commented Aug 17, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Aug 17, 2025

📌 Commit f70c98f has been approved by oli-obk

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 17, 2025
@jieyouxu
Copy link
Member

@bors p=4 (rollup interleaving)

bors added a commit that referenced this pull request Aug 19, 2025
Constify Eq, Ord, PartialOrd

Adds `#[const_trait]` and impls for `Eq`, `Ord`, `PartialOrd`. Impl for some other traits (e.g., slices and arrays) are blocked mainly on const closures (#106003).
For TypeId Ord we need const pointer comparison (#53020)
Tracking issue #143800
@bors
Copy link
Collaborator

bors commented Aug 19, 2025

⌛ Testing commit f70c98f with merge 953f713...

@rust-log-analyzer
Copy link
Collaborator

The job aarch64-apple failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
failures:

---- [codegen] tests/codegen-llvm/array-cmp.rs stdout ----

error: verification with 'FileCheck' failed
status: exit status: 1
command: "/Users/runner/work/rust/rust/build/aarch64-apple-darwin/ci-llvm/bin/FileCheck" "--input-file" "/Users/runner/work/rust/rust/build/aarch64-apple-darwin/test/codegen-llvm/array-cmp/array-cmp.ll" "/Users/runner/work/rust/rust/tests/codegen-llvm/array-cmp.rs" "--check-prefix=CHECK" "--allow-unused-prefixes" "--dump-input-context" "100"
stdout: none
--- stderr -------------------------------
/Users/runner/work/rust/rust/tests/codegen-llvm/array-cmp.rs:51:12: error: CHECK: expected string not found in input
 // CHECK: [[L10]]:
           ^
/Users/runner/work/rust/rust/build/aarch64-apple-darwin/test/codegen-llvm/array-cmp/array-cmp.ll:72:72: note: scanning from here
 br i1 %_5.i10.not.i.i.i, label %bb1.i, label %bb11.split.loop.exit15.i
                                                                       ^
/Users/runner/work/rust/rust/build/aarch64-apple-darwin/test/codegen-llvm/array-cmp/array-cmp.ll:72:72: note: with "L10" equal to "bb1.i"
 br i1 %_5.i10.not.i.i.i, label %bb1.i, label %bb11.split.loop.exit15.i
                                                                       ^
/Users/runner/work/rust/rust/build/aarch64-apple-darwin/test/codegen-llvm/array-cmp/array-cmp.ll:74:59: note: possible intended match here
_ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E.exit: ; preds = %bb6.i.i.1.i, %bb11.split.loop.exit13.i, %bb11.split.loop.exit15.i
                                                          ^

Input file: /Users/runner/work/rust/rust/build/aarch64-apple-darwin/test/codegen-llvm/array-cmp/array-cmp.ll
Check file: /Users/runner/work/rust/rust/tests/codegen-llvm/array-cmp.rs

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            1: ; ModuleID = 'array_cmp.ea05bcb84312f8f9-cgu.0' 
            2: source_filename = "array_cmp.ea05bcb84312f8f9-cgu.0" 
            3: target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" 
            4: target triple = "arm64-apple-macosx11.0.0" 
            5:  
            6: ; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable 
            7: define noundef zeroext i1 @compare() unnamed_addr #0 { 
            8: start: 
            9:  ret i1 true 
           10: } 
           11:  
           12: ; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read, inaccessiblemem: readwrite) uwtable 
           13: define noundef zeroext i1 @array_of_tuple_le(ptr noalias noundef readonly align 2 captures(none) dereferenceable(8) %a, ptr noalias noundef readonly align 2 captures(none) dereferenceable(8) %b) unnamed_addr #1 personality ptr @rust_eh_personality { 
           14: start: 
           15:  tail call void @llvm.experimental.noalias.scope.decl(metadata !2) 
           16:  tail call void @llvm.experimental.noalias.scope.decl(metadata !5) 
           17:  tail call void @llvm.experimental.noalias.scope.decl(metadata !7) 
           18:  tail call void @llvm.experimental.noalias.scope.decl(metadata !10) 
           19:  tail call void @llvm.experimental.noalias.scope.decl(metadata !12) 
           20:  tail call void @llvm.experimental.noalias.scope.decl(metadata !15) 
           21:  tail call void @llvm.experimental.noalias.scope.decl(metadata !17) 
           22:  tail call void @llvm.experimental.noalias.scope.decl(metadata !20) 
           23:  %lhs.i.i.i.i = load i16, ptr %a, align 2, !alias.scope !22, !noalias !23, !noundef !24 
           24:  %rhs.i.i.i.i = load i16, ptr %b, align 2, !alias.scope !23, !noalias !22, !noundef !24 
           25:  %_5.i.i.i.i = icmp eq i16 %lhs.i.i.i.i, %rhs.i.i.i.i 
           26:  br i1 %_5.i.i.i.i, label %bb6.i.i.i, label %bb11.split.loop.exit13.i 
           27:  
           28: bb1.i: ; preds = %bb6.i.i.i 
           29:  %_17.1.i = getelementptr inbounds nuw i8, ptr %a, i64 4 
           30:  %_21.1.i = getelementptr inbounds nuw i8, ptr %b, i64 4 
           31:  tail call void @llvm.experimental.noalias.scope.decl(metadata !25) 
           32:  tail call void @llvm.experimental.noalias.scope.decl(metadata !27) 
           33:  tail call void @llvm.experimental.noalias.scope.decl(metadata !29) 
           34:  tail call void @llvm.experimental.noalias.scope.decl(metadata !31) 
           35:  tail call void @llvm.experimental.noalias.scope.decl(metadata !33) 
           36:  tail call void @llvm.experimental.noalias.scope.decl(metadata !35) 
           37:  %lhs.i.i.i.1.i = load i16, ptr %_17.1.i, align 2, !alias.scope !37, !noalias !38, !noundef !24 
           38:  %rhs.i.i.i.1.i = load i16, ptr %_21.1.i, align 2, !alias.scope !38, !noalias !37, !noundef !24 
           39:  %_5.i.i.i.1.i = icmp eq i16 %lhs.i.i.i.1.i, %rhs.i.i.i.1.i 
           40:  br i1 %_5.i.i.i.1.i, label %bb6.i.i.1.i, label %bb11.split.loop.exit13.i 
           41:  
           42: bb6.i.i.1.i: ; preds = %bb1.i 
           43:  %_10.i.i.1.i = getelementptr inbounds nuw i8, ptr %a, i64 6 
           44:  %_11.i.i.1.i = getelementptr inbounds nuw i8, ptr %b, i64 6 
           45:  tail call void @llvm.experimental.noalias.scope.decl(metadata !39) 
           46:  tail call void @llvm.experimental.noalias.scope.decl(metadata !42) 
           47:  %lhs.i8.i.i.1.i = load i16, ptr %_10.i.i.1.i, align 2, !alias.scope !44, !noalias !45, !noundef !24 
           48:  %rhs.i9.i.i.1.i = load i16, ptr %_11.i.i.1.i, align 2, !alias.scope !45, !noalias !44, !noundef !24 
           49:  %_5.i10.not.i.i.1.i = icmp eq i16 %lhs.i8.i.i.1.i, %rhs.i9.i.i.1.i 
           50:  br i1 %_5.i10.not.i.i.1.i, label %_ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E.exit, label %bb11.split.loop.exit15.i 
           51:  
           52: bb11.split.loop.exit13.i: ; preds = %bb1.i, %start 
           53:  %lhs.i.i.i.lcssa.i = phi i16 [ %lhs.i.i.i.i, %start ], [ %lhs.i.i.i.1.i, %bb1.i ] 
           54:  %rhs.i.i.i.lcssa.i = phi i16 [ %rhs.i.i.i.i, %start ], [ %rhs.i.i.i.1.i, %bb1.i ] 
           55:  %_6.i.i.i.le.i = icmp sle i16 %lhs.i.i.i.lcssa.i, %rhs.i.i.i.lcssa.i 
           56:  br label %_ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E.exit 
           57:  
           58: bb11.split.loop.exit15.i: ; preds = %bb6.i.i.i, %bb6.i.i.1.i 
           59:  %lhs.i8.i.i.lcssa.i = phi i16 [ %lhs.i8.i.i.i, %bb6.i.i.i ], [ %lhs.i8.i.i.1.i, %bb6.i.i.1.i ] 
           60:  %rhs.i9.i.i.lcssa.i = phi i16 [ %rhs.i9.i.i.i, %bb6.i.i.i ], [ %rhs.i9.i.i.1.i, %bb6.i.i.1.i ] 
           61:  %narrow.i.i.le.i = icmp ult i16 %lhs.i8.i.i.lcssa.i, %rhs.i9.i.i.lcssa.i 
           62:  br label %_ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E.exit 
           63:  
           64: bb6.i.i.i: ; preds = %start 
           65:  %_10.i.i.i = getelementptr inbounds nuw i8, ptr %a, i64 2 
           66:  %_11.i.i.i = getelementptr inbounds nuw i8, ptr %b, i64 2 
           67:  tail call void @llvm.experimental.noalias.scope.decl(metadata !46) 
           68:  tail call void @llvm.experimental.noalias.scope.decl(metadata !48) 
           69:  %lhs.i8.i.i.i = load i16, ptr %_10.i.i.i, align 2, !alias.scope !50, !noalias !51, !noundef !24 
           70:  %rhs.i9.i.i.i = load i16, ptr %_11.i.i.i, align 2, !alias.scope !51, !noalias !50, !noundef !24 
           71:  %_5.i10.not.i.i.i = icmp eq i16 %lhs.i8.i.i.i, %rhs.i9.i.i.i 
           72:  br i1 %_5.i10.not.i.i.i, label %bb1.i, label %bb11.split.loop.exit15.i 
check:51'0                                                                            X error: no match found
check:51'1                                                                              with "L10" equal to "bb1.i"
           73:  
check:51'0     ~
           74: _ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E.exit: ; preds = %bb6.i.i.1.i, %bb11.split.loop.exit13.i, %bb11.split.loop.exit15.i 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
check:51'2                                                               ?                                                                               possible intended match
           75:  %_0.sroa.0.0.i = phi i1 [ %_6.i.i.i.le.i, %bb11.split.loop.exit13.i ], [ %narrow.i.i.le.i, %bb11.split.loop.exit15.i ], [ true, %bb6.i.i.1.i ] 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           76:  ret i1 %_0.sroa.0.0.i 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~
           77: } 
check:51'0     ~~
           78:  
check:51'0     ~
           79: ; Function Attrs: nounwind uwtable 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           80: declare noundef range(i32 0, 10) i32 @rust_eh_personality(i32 noundef, i32 noundef, i64 noundef, ptr noundef, ptr noundef) unnamed_addr #2 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           81:  
check:51'0     ~
           82: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           83: declare void @llvm.experimental.noalias.scope.decl(metadata) #3 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           84:  
check:51'0     ~
           85: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" } 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           86: attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read, inaccessiblemem: readwrite) uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" } 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           87: attributes #2 = { nounwind uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="apple-m1" } 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           88: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           89:  
check:51'0     ~
           90: !llvm.module.flags = !{!0} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
           91: !llvm.ident = !{!1} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~
           92:  
check:51'0     ~
           93: !0 = !{i32 8, !"PIC Level", i32 2} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           94: !1 = !{!"rustc version 1.91.0-nightly (953f71322 2025-08-19)"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           95: !2 = !{!3} 
check:51'0     ~~~~~~~~~~~
           96: !3 = distinct !{!3, !4, !"_ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E: %left.0"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           97: !4 = distinct !{!4, !"_ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           98: !5 = !{!6} 
check:51'0     ~~~~~~~~~~~
           99: !6 = distinct !{!6, !4, !"_ZN4core5slice3cmp13chaining_impl17h5a59d2cbaa8836d3E: %right.0"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          100: !7 = !{!8} 
check:51'0     ~~~~~~~~~~~
          101: !8 = distinct !{!8, !9, !"_ZN4core3ops8function2Fn4call17h160d964305fd52caE: argument 0"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          102: !9 = distinct !{!9, !"_ZN4core3ops8function2Fn4call17h160d964305fd52caE"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          103: !10 = !{!11} 
check:51'0     ~~~~~~~~~~~~~
          104: !11 = distinct !{!11, !9, !"_ZN4core3ops8function2Fn4call17h160d964305fd52caE: argument 1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          105: !12 = !{!13} 
check:51'0     ~~~~~~~~~~~~~
          106: !13 = distinct !{!13, !14, !"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$13__chaining_le17h94315e4246cb9b27E: %self"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          107: !14 = distinct !{!14, !"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$13__chaining_le17h94315e4246cb9b27E"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          108: !15 = !{!16} 
check:51'0     ~~~~~~~~~~~~~
          109: !16 = distinct !{!16, !14, !"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$13__chaining_le17h94315e4246cb9b27E: %other"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          110: !17 = !{!18} 
check:51'0     ~~~~~~~~~~~~~
          111: !18 = distinct !{!18, !19, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$i16$GT$13__chaining_le17h65bae47fe1a7cef3E: %self"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          112: !19 = distinct !{!19, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$i16$GT$13__chaining_le17h65bae47fe1a7cef3E"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          113: !20 = !{!21} 
check:51'0     ~~~~~~~~~~~~~
          114: !21 = distinct !{!21, !19, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$i16$GT$13__chaining_le17h65bae47fe1a7cef3E: %other"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          115: !22 = !{!18, !13, !8, !3} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~
          116: !23 = !{!21, !16, !11, !6} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          117: !24 = !{} 
check:51'0     ~~~~~~~~~~
          118: !25 = !{!26} 
check:51'0     ~~~~~~~~~~~~~
          119: !26 = distinct !{!26, !9, !"_ZN4core3ops8function2Fn4call17h160d964305fd52caE: argument 0:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          120: !27 = !{!28} 
check:51'0     ~~~~~~~~~~~~~
          121: !28 = distinct !{!28, !9, !"_ZN4core3ops8function2Fn4call17h160d964305fd52caE: argument 1:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          122: !29 = !{!30} 
check:51'0     ~~~~~~~~~~~~~
          123: !30 = distinct !{!30, !14, !"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$13__chaining_le17h94315e4246cb9b27E: %self:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          124: !31 = !{!32} 
check:51'0     ~~~~~~~~~~~~~
          125: !32 = distinct !{!32, !14, !"_ZN4core5tuple65_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$$LP$U$C$T$RP$$GT$13__chaining_le17h94315e4246cb9b27E: %other:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          126: !33 = !{!34} 
check:51'0     ~~~~~~~~~~~~~
          127: !34 = distinct !{!34, !19, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$i16$GT$13__chaining_le17h65bae47fe1a7cef3E: %self:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          128: !35 = !{!36} 
check:51'0     ~~~~~~~~~~~~~
          129: !36 = distinct !{!36, !19, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$i16$GT$13__chaining_le17h65bae47fe1a7cef3E: %other:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          130: !37 = !{!34, !30, !26, !3} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          131: !38 = !{!36, !32, !28, !6} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          132: !39 = !{!40} 
check:51'0     ~~~~~~~~~~~~~
          133: !40 = distinct !{!40, !41, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$u16$GT$13__chaining_le17h8fe68ba1357aba2dE: %self:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          134: !41 = distinct !{!41, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$u16$GT$13__chaining_le17h8fe68ba1357aba2dE"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          135: !42 = !{!43} 
check:51'0     ~~~~~~~~~~~~~
          136: !43 = distinct !{!43, !41, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$u16$GT$13__chaining_le17h8fe68ba1357aba2dE: %other:It1"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          137: !44 = !{!40, !30, !26, !3} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          138: !45 = !{!43, !32, !28, !6} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          139: !46 = !{!47} 
check:51'0     ~~~~~~~~~~~~~
          140: !47 = distinct !{!47, !41, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$u16$GT$13__chaining_le17h8fe68ba1357aba2dE: %self"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          141: !48 = !{!49} 
check:51'0     ~~~~~~~~~~~~~
          142: !49 = distinct !{!49, !41, !"_ZN4core3cmp5impls55_$LT$impl$u20$core..cmp..PartialOrd$u20$for$u20$u16$GT$13__chaining_le17h8fe68ba1357aba2dE: %other"} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          143: !50 = !{!47, !13, !8, !3} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~
          144: !51 = !{!49, !16, !11, !6} 
check:51'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>
------------------------------------------



@bors
Copy link
Collaborator

bors commented Aug 19, 2025

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 19, 2025
@clarfonthey
Copy link
Contributor

clarfonthey commented Aug 20, 2025

Appears to be a legitimate codegen failure related to Ord, but I'm not exactly sure why there'd be a regression here. Might just fix itself with a rebase.

@Randl
Copy link
Contributor Author

Randl commented Aug 20, 2025

Ok. It is a legitimate codegen failure; I can reproduce it locally, including after rebase. I do not understand what is specifically wrong with the codegen (cc @scottmcm ), but the reason appears to be this change:

https://github.com/rust-lang/rust/pull/144847/files#diff-b3bc3e9849f0b9690cf061db39e229a23495e0ff8dd3eded8e2ac5d9bb3eb7a7L215-R232

I'm unsure why the difference between the while loop and the for loop results in incorrect codegen. I can revert this specific change for now (it doesn't give us slice Ord anyway because that requires const closures, for example, in

let len_chain = |a: &_, b: &_| ControlFlow::Break(usize::partial_cmp(a, b));

) until we either figure out how to make the while loop work with codegen, or we can use for in const code (though if I understand correctly, this will require iterators, which by themselves will probably depend on this code).

@bors
Copy link
Collaborator

bors commented Aug 20, 2025

☔ The latest upstream changes (presumably #145644) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
perf-regression Performance regression. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.