Skip to content

Make TypeId const comparable #142789

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 12 commits into
base: master
Choose a base branch
from
Open

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Jun 20, 2025

This should unblock stabilizing const TypeId::of and allow us to progress into any possible future we want to take TypeId to.

To achieve that TypeId now contains 16 / size_of<usize>() pointers which each are actually just size_of<usize>() bytes of the stable hash. At compile-time these pointers cannot be dereferenced or otherwise inspected (at present doing so might ICE the compiler). Preventing inspection of this data allows us to refactor TypeId to any other scheme in the future without breaking anyone who was tempted to transmute TypeId to obtain the hash at compile-time.

cc @eddyb for their previous work on #95845 (which we still can do in the future if we want to get rid of the hash as the final thing that declares two TypeIds as equal).

r? @RalfJung

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. 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 Jun 20, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 20, 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

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

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

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@rust-log-analyzer

This comment has been minimized.

@oli-obk oli-obk force-pushed the constable-type-id branch from 3cddd21 to 1fd7b66 Compare June 21, 2025 10:20
@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member

It will be a while until I have the capacity to review a PR of this scale.

Meanwhile, could you say a bit more about the architecture of the change? It seems you want for the "new kind of allocation" approach, but it's not clear from the PR description how exactly that shows up in TypeId.

Also, I am definitely not comfortable landing this by myself, I can only review the const-eval parts. Changing the representation of TypeId has ramifications well beyond that that I do not feel qualified to evaluate -- I think an MCP would be justified.

@rustbot
Copy link
Collaborator

rustbot commented Jun 21, 2025

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 21, 2025

Well, I got private feedback yesterday that instead of encoding a 16 byte value as an 8 byte pointer to the 16 byte value and an 8 byte hash, I should just do the thing where we split up type id internally into pointer sized chunks and codegen will make a hash out of it again.

TLDR: no changes to runtime type id anymore in the latest revision of this PR. Only compile-time type id is now a bit funny

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 21, 2025

It will be a while until I have the capacity to review a PR of this scale.

I'm splitting unrelated parts out, so the high level feedback is already useful and I'll look for libs and codegen ppl to review the appropriate parts

@rust-log-analyzer

This comment has been minimized.

jdonszelmann added a commit to jdonszelmann/rust that referenced this pull request Jun 23, 2025
Make `PartialEq` a `const_trait`

r? `@fee1-dead` or `@compiler-errors`

something generally useful but also required for rust-lang#142789
jdonszelmann added a commit to jdonszelmann/rust that referenced this pull request Jun 23, 2025
Make `PartialEq` a `const_trait`

r? ``@fee1-dead`` or ``@compiler-errors``

something generally useful but also required for rust-lang#142789
rust-timer added a commit that referenced this pull request Jun 23, 2025
Rollup merge of #142822 - oli-obk:const-partial-eq, r=fee1-dead

Make `PartialEq` a `const_trait`

r? ``@fee1-dead`` or ``@compiler-errors``

something generally useful but also required for #142789
@bors
Copy link
Collaborator

bors commented Jun 23, 2025

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

@oli-obk oli-obk force-pushed the constable-type-id branch 2 times, most recently from b8a7a10 to 1c47a64 Compare June 24, 2025 09:25
@rust-log-analyzer

This comment has been minimized.

@oli-obk oli-obk force-pushed the constable-type-id branch from 1c47a64 to bcb4aa2 Compare June 24, 2025 13:02
@rust-log-analyzer

This comment has been minimized.

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 27, 2025

I don't understand, why do we need such a map?

if we have a TypeId in CTFE, and that is just 16 bytes of a hash, and we have a comptime/reflection intrinsic like fn size_of_type_id(id: TypeId) -> usize;, the mir interpreter needs to be able to go from those hash bytes to a Ty<'tcx>, and the hash is obviously not reversible.

Both solutions 1 & 2 contain an AllocId that just gives me the right information straight away, but I can also just fill in a hash map whenever const eval invokes type_id to get a TypeId, and then aggregate that hash map across all crates via their metadata, it just is an ugly solution

}
GlobalAlloc::Static(def_id) => {
assert!(self.tcx.is_static(def_id));
assert!(!self.tcx.is_thread_local_static(def_id));
self.get_static(def_id)
}
GlobalAlloc::Type { ty, segment } => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This code path ignores the pointer offset. Should probably error if it is not 0 instead of silently allowing people to offset it as they want without that actually doing anything

Copy link
Contributor Author

Choose a reason for hiding this comment

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

or we add the offset to the hash value, which is technically what was done by the user

@oli-obk oli-obk force-pushed the constable-type-id branch from 9009013 to 79fa8f8 Compare June 27, 2025 08:14
@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member

RalfJung commented Jun 27, 2025

if we have a TypeId in CTFE, and that is just 16 bytes of a hash, and we have a comptime/reflection intrinsic like fn size_of_type_id(id: TypeId) -> usize;, the mir interpreter needs to be able to go from those hash bytes to a Ty<'tcx>, and the hash is obviously not reversible.

So suddenly the scope creeped from just supporting type_id comparison to full compile-time reflection? That's a completely different beast and requires a lot of design still, and nothing in the PR description or prior discussion prepared me for any sort of involvement of reflection in this change. I'd prefer to focus on one thing at a time... or at least, I'd like to know all relevant design goals before being asked to review a design.^^

If this must also provide reflection, we have to go back to square 0 and think about principled solutions. I still don't like the hacks here... but I'll wait for a complete description of the design goals to avoid being surprised with more previously unmentioned constraints again.^^

@rust-log-analyzer

This comment has been minimized.

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 27, 2025

That's why this design is forward compatible to anything we want to do without affecting the runtime layout. I don't want to scope creep either XD

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 27, 2025

I don't want to leave TypeId in limbo state while we figure out the entire design space of everything we ever want from it. I would rather put it into a state that is strictly forward compatible with anything we could want, thus this PR.

@RalfJung
Copy link
Member

I wouldn't mind that if there was some beautiful solution that also happened to be good for reflection -- but I don't think the solution in this PR qualifies as "beautiful". And I'd rather not have tricky hacks in the compiler that are motivated by speculative future extensions. We can always add these hacks later if it turns out that we really do want to make TypeId the cornerstone of reflection.

So for the sake of avoiding XY-like situations, I'd really appreciate if you could spell out the motivation of a tricky, non-obvious change like this in full upfront, rather than revealing it piecewise during the discussion.


Being aware of your future plans now, here's another possible proposal:

  • Let's equip the first pointer-sized chunk of TypeId with provenance, and use that provenance to track the full identity of the type in question. The raw bytes of the TypeId will still be the actual hash, so if there is a TypeId in a const value, codegen just has to drop the provenance and preserve the raw bytes. IOW, this acts as-if the allocation that the pointer "points to" always lives at address 0.
  • The type_id_eq intrinsic is also used at runtime so that Miri can take into account the provenance for comparison.

I'm honestly still not super happy with that proposal, but you seem set on doing something along these lines and this is a compromise that I think I can live with, if it doesn't turn out to have unexpected problems. This will still require a bunch of special hacks to make these "allocations" have a known-0 base address, but I can't think of a better way (making the base address be the hash is not better, IMO).

The proposal has one upside compared to item 3 in my previous list, which is that the opsem for TypeId actually is entirely independent of the hash function. So the imperfection of hashing moves from being truly in the language to being a compiler implementation detail.

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 27, 2025

So for the sake of avoiding XY-like situations, I'd really appreciate if you could spell out the motivation of a tricky, non-obvious change like this in full upfront, rather than revealing it piecewise during the discussion.

Fair. Tho the idea that we can (ab)use this for reflection came independently from this design. The motivation was indeed just to get this stabilized, and since the cost seemed small to me with this PR I assumed option 3 was irrelevant

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 27, 2025

I'm honestly still not super happy with that proposal, but you seem set on doing something along these lines and this is a compromise that I think I can live with, if it doesn't turn out to have unexpected problems. This will still require a bunch of special hacks to make these "allocations" have a known-0 base address, but I can't think of a better way (making the base address be the hash is not better, IMO).

If we're exposing any bytes to const eval, we can just expose everything and revisit adding provenance when T-lang approves a reflection experiment. I'll create a separate PR for just making the PartialEq impl const and propose moving TypeId to stabilization along with stabilizing the const trait impl without stabilizing const traits in general

@RalfJung
Copy link
Member

If we're exposing any bytes to const eval, we can just expose everything

Having provenance on some bytes still means we'd appropriately error out if someone just transmutes the entire thing to u128 in const-eval, or something like that. We'd only be truly exposing the "tail", i.e., everything after the first ptr-sized chunk.

@oli-obk
Copy link
Contributor Author

oli-obk commented Jun 27, 2025

I meant more in the sense of "Ralf is happy with this approach" XD

I would prefer to prevent such transmutes failing by having provenance $somewhere, so I'll stop talking myself out of it now 😆

@oli-obk oli-obk force-pushed the constable-type-id branch from afa74de to 6fea6c3 Compare June 27, 2025 13:58
@rustbot
Copy link
Collaborator

rustbot commented Jun 27, 2025

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

@oli-obk oli-obk force-pushed the constable-type-id branch from 6fea6c3 to 2e8cece Compare June 27, 2025 14:24
@rust-log-analyzer
Copy link
Collaborator

The job aarch64-gnu-llvm-19-1 failed! Check out the build log: (web) (plain)

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

---- [codegen] tests/codegen/error-provide.rs stdout ----

error: verification with 'FileCheck' failed
status: exit status: 1
command: "/usr/lib/llvm-19/bin/FileCheck" "--input-file" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen/error-provide/error-provide.ll" "/checkout/tests/codegen/error-provide.rs" "--check-prefix=CHECK" "--allow-unused-prefixes" "--dump-input-context" "100"
stdout: none
--- stderr -------------------------------
/checkout/tests/codegen/error-provide.rs:40:17: error: CHECK-NEXT: expected string not found in input
 // CHECK-NEXT: %[[SCRUTINEE:[^ ]+]] = load i64, ptr
                ^
/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen/error-provide/error-provide.ll:24:7: note: scanning from here
start:
      ^
/checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen/error-provide/error-provide.ll:25:18: note: possible intended match here
 %_18.sroa.0.0.copyload.i = load ptr, ptr %request.0, align 8, !noalias !2
                 ^

Input file: /checkout/obj/build/aarch64-unknown-linux-gnu/test/codegen/error-provide/error-provide.ll
Check file: /checkout/tests/codegen/error-provide.rs

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

Input was:
<<<<<<
           1: ; ModuleID = 'error_provide.92b80c987a7459c3-cgu.0' 
           2: source_filename = "error_provide.92b80c987a7459c3-cgu.0" 
           3: target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32" 
           4: target triple = "aarch64-unknown-linux-gnu" 
           5:  
           6: @alloc_9f80ff4206777b7f9f5e9dc6227b3b5d = private unnamed_addr constant [13 x i8] c"Example Error", align 1 
           7:  
           8: ; <error_provide::MyError as core::fmt::Display>::fmt 
           9: ; Function Attrs: uwtable 
          10: define noundef zeroext i1 @"_ZN61_$LT$error_provide..MyError$u20$as$u20$core..fmt..Display$GT$3fmt17h6640350f97591b01E"(ptr noalias nocapture noundef nonnull readonly align 1 %self, ptr noalias nocapture noundef readonly align 8 dereferenceable(32) %f) unnamed_addr #0 { 
          11: bb8.i: 
          12:  %0 = getelementptr inbounds i8, ptr %f, i64 16 
          13:  %f.val = load ptr, ptr %0, align 8, !nonnull !2, !noundef !2 
          14:  %1 = getelementptr inbounds i8, ptr %f, i64 24 
          15:  %f.val1 = load ptr, ptr %1, align 8, !nonnull !2, !noundef !2 
          16:  %2 = getelementptr inbounds i8, ptr %f.val1, i64 24 
          17:  %3 = load ptr, ptr %2, align 8, !invariant.load !2, !noalias !3, !nonnull !2 
          18:  %4 = tail call noundef zeroext i1 %3(ptr noundef nonnull align 1 %f.val, ptr noalias noundef nonnull readonly align 1 @alloc_9f80ff4206777b7f9f5e9dc6227b3b5d, i64 noundef 13), !noalias !3 
          19:  ret i1 %4 
          20: } 
          21:  
          22: ; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) uwtable 
          23: define void @provide(ptr noalias noundef nonnull readonly align 1 %self, ptr nocapture noundef nonnull align 8 %request.0, ptr noalias nocapture noundef readonly align 8 dereferenceable(24) %request.1) unnamed_addr #1 personality ptr @rust_eh_personality { 
          24: start: 
next:40'0           X error: no match found
          25:  %_18.sroa.0.0.copyload.i = load ptr, ptr %request.0, align 8, !noalias !2 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
next:40'1                      ?                                                          possible intended match
          26:  %_18.sroa.4.0.self.0.sroa_idx.i = getelementptr inbounds i8, ptr %request.0, i64 8 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          27:  %_18.sroa.4.0.copyload.i = load ptr, ptr %_18.sroa.4.0.self.0.sroa_idx.i, align 8, !noalias !2 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          28:  %_0.i.i.not.i.i.i = icmp eq ptr %_18.sroa.0.0.copyload.i, inttoptr (i64 8370573293851571771 to ptr) 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          29:  %_0.i.i.not.1.i.i.i = icmp eq ptr %_18.sroa.4.0.copyload.i, inttoptr (i64 -4971850821883717690 to ptr) 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          30:  %spec.select.i.i = select i1 %_0.i.i.not.i.i.i, i1 %_0.i.i.not.1.i.i.i, i1 false 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          31:  br i1 %spec.select.i.i, label %bb9.i, label %_ZN4core5error7Request7provide17h911d39595bafe488E.exit 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          32:  
next:40'0     ~
          33: bb9.i: ; preds = %start 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~
          34:  %_15.i = getelementptr inbounds i8, ptr %request.0, i64 16 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          35:  %0 = load ptr, ptr %_15.i, align 8, !noalias !6, !align !10, !noundef !2 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          36:  %.not.i = icmp eq ptr %0, null 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          37:  br i1 %.not.i, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31.sink.split, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          38:  
next:40'0     ~
          39: _ZN4core5error7Request7provide17h911d39595bafe488E.exit: ; preds = %start 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          40:  %_0.i.i.not.i.i.i4 = icmp eq ptr %_18.sroa.0.0.copyload.i, inttoptr (i64 -3248343714577738390 to ptr) 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          41:  %_0.i.i.not.1.i.i.i5 = icmp eq ptr %_18.sroa.4.0.copyload.i, inttoptr (i64 -2507171614806537706 to ptr) 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          42:  %spec.select.i.i6 = select i1 %_0.i.i.not.i.i.i4, i1 %_0.i.i.not.1.i.i.i5, i1 false 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          43:  br i1 %spec.select.i.i6, label %bb9.i7, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          44:  
next:40'0     ~
          45: bb9.i7: ; preds = %_ZN4core5error7Request7provide17h911d39595bafe488E.exit 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          46:  %_15.i8 = getelementptr inbounds i8, ptr %request.0, i64 16 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          47:  %1 = load ptr, ptr %_15.i8, align 8, !noalias !2, !align !10, !noundef !2 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          48:  %.not.i9 = icmp eq ptr %1, null 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          49:  br i1 %.not.i9, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31.sink.split, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          50:  
next:40'0     ~
          51: _ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit: ; preds = %_ZN4core5error7Request7provide17h911d39595bafe488E.exit 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          52:  %_0.i.i.not.i.i.i14 = icmp eq ptr %_18.sroa.0.0.copyload.i, inttoptr (i64 3519220745057012639 to ptr) 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          53:  %_0.i.i.not.1.i.i.i15 = icmp eq ptr %_18.sroa.4.0.copyload.i, inttoptr (i64 4036131344055433813 to ptr) 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          54:  %spec.select.i.i16 = select i1 %_0.i.i.not.i.i.i14, i1 %_0.i.i.not.1.i.i.i15, i1 false 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          55:  br i1 %spec.select.i.i16, label %bb9.i17, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          56:  
next:40'0     ~
          57: bb9.i17: ; preds = %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          58:  %_15.i18 = getelementptr inbounds i8, ptr %request.0, i64 16 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          59:  %2 = load ptr, ptr %_15.i18, align 8, !noalias !11, !align !10, !noundef !2 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          60:  %.not.i19 = icmp eq ptr %2, null 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          61:  br i1 %.not.i19, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31.sink.split, label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          62:  
next:40'0     ~
          63: _ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31.sink.split: ; preds = %bb9.i17, %bb9.i7, %bb9.i 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          64:  %_15.i8.sink = phi ptr [ %_15.i, %bb9.i ], [ %_15.i8, %bb9.i7 ], [ %_15.i18, %bb9.i17 ] 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          65:  store ptr %self, ptr %_15.i8.sink, align 8, !noalias !2 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          66:  br label %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          67:  
next:40'0     ~
          68: _ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31: ; preds = %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit31.sink.split, %bb9.i7, %bb9.i, %bb9.i17, %_ZN4core5error7Request7provide17hd077a3cb41c3a346E.exit 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          69:  ret void 
next:40'0     ~~~~~~~~~~
          70: } 
next:40'0     ~~
          71:  
next:40'0     ~
          72: ; Function Attrs: nounwind uwtable 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          73: declare noundef range(i32 0, 10) i32 @rust_eh_personality(i32 noundef, i32 noundef, i64 noundef, ptr noundef, ptr noundef) unnamed_addr #2 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          74:  
next:40'0     ~
          75: attributes #0 = { uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="generic" "target-features"="+v8a,+outline-atomics" } 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          76: attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="generic" "target-features"="+v8a,+outline-atomics" } 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          77: attributes #2 = { nounwind uwtable "frame-pointer"="non-leaf" "probe-stack"="inline-asm" "target-cpu"="generic" "target-features"="+v8a,+outline-atomics" } 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          78:  
next:40'0     ~
          79: !llvm.module.flags = !{!0} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
          80: !llvm.ident = !{!1} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~
          81:  
next:40'0     ~
          82: !0 = !{i32 8, !"PIC Level", i32 2} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          83: !1 = !{!"rustc version 1.90.0-nightly (d98720274 2025-06-27)"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          84: !2 = !{} 
next:40'0     ~~~~~~~~~
          85: !3 = !{!4} 
next:40'0     ~~~~~~~~~~~
          86: !4 = distinct !{!4, !5, !"_ZN4core3fmt9Formatter9write_fmt17h38fa9b39a97ed391E: %fmt"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          87: !5 = distinct !{!5, !"_ZN4core3fmt9Formatter9write_fmt17h38fa9b39a97ed391E"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          88: !6 = !{!7, !9} 
next:40'0     ~~~~~~~~~~~~~~~
          89: !7 = distinct !{!7, !8, !"_ZN4core5error7Request7provide17h911d39595bafe488E: %self.1"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          90: !8 = distinct !{!8, !"_ZN4core5error7Request7provide17h911d39595bafe488E"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          91: !9 = distinct !{!9, !8, !"_ZN4core5error7Request7provide17h911d39595bafe488E: %value"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          92: !10 = !{i64 1} 
next:40'0     ~~~~~~~~~~~~~~~
          93: !11 = !{!12, !14} 
next:40'0     ~~~~~~~~~~~~~~~~~~
          94: !12 = distinct !{!12, !13, !"_ZN4core5error7Request7provide17hf352b555f17e8a09E: %self.1"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          95: !13 = distinct !{!13, !"_ZN4core5error7Request7provide17hf352b555f17e8a09E"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          96: !14 = distinct !{!14, !13, !"_ZN4core5error7Request7provide17hf352b555f17e8a09E: %value"} 
next:40'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>>>>
------------------------------------------



Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. 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.

9 participants