Skip to content

fix ICE in generic_const_parameter_types with inherents - #161858

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
khyperia:ice-generic_const_parameter_types
Aug 29, 2026
Merged

fix ICE in generic_const_parameter_types with inherents#161858
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
khyperia:ice-generic_const_parameter_types

Conversation

@khyperia

Copy link
Copy Markdown
Member

tracking issue: #137626

relevant PR where the code was added: #154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

  • normalize_canonicalized_inherent_projection is called with AliasTermKind::InherentConst with the generic args being in "self form", i.e. [ThreeTypes<u8, u16, u32>]
  • traits::normalize_inherent_projection is called with said alias
    • it calls compute_inherent_assoc_term_args, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. [u8, u16, u32]
    • it then calls const_of_item and instantiates with [u8, u16, u32]. this is correct and good, const_of_item expects "impl form" args.
    • it then calls push_const_arg_has_type_obligation
      • which calls type_of and instantiates with [u8, u16, u32] to fetch the type of the const, to be able to register a ConstArgHasType. this is correct and good, type_of expects "impl form" args.
    • traits::normalize_inherent_projection returns, dropping the impl form args it computed
  • normalize_canonicalized_inherent_projection calls ocx.register_obligations(const_arg_has_type_obligation(...)), passing goal. Remember that goal has the original "self args" generic arg format.
    • const_arg_has_type_obligation calls type_of and instantiates with [ThreeTypes<u8, u16, u32>]. This is no good very bad!! type_of expects "impl form" args, not "self form"!!
    • ICE!! type parameter T3/#2 (T3/#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]

The reason I filed this under feature(generic_const_parameter_types) is because for this bug to manifest, type_of must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

normalize_inherent_projection already registers a ConstArgHasType. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU

@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. labels Aug 27, 2026
@rustbot

rustbot commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

BoxyUwU is currently at their maximum review capacity.
They may take a while to respond.

@BoxyUwU BoxyUwU left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you check whether the function for normalizing trait projections also checks this twice? If so that should be yeet too ✨ But yeah this PR makes sense to me 👍

View changes since this review

@khyperia
khyperia force-pushed the ice-generic_const_parameter_types branch from 6e48245 to d471202 Compare August 28, 2026 04:42
@khyperia

Copy link
Copy Markdown
Member Author

Can you check whether the function for normalizing trait projections also checks this twice? If so that should be yeet too ✨ But yeah this PR makes sense to me 👍

ough, I did go looking for it when I wrote this PR and didn't find it, but yes, it also happens. It's very deep within the project machinery though, and it only happens for ImplSource::UserDefined (in confirm_impl_candidate), not ImplSource::Builtin or ProjectionCandidate::{ParamEnv, Object, TraitDef}, but that's maaaaybe fine? I'm unsure if "unsoundness possible due to badly defining your own lang items" is like, a valid bug. Anyway, TBH I'm a little more scared of yeeting this for trait projections though... relying on the const value matching the type of the impl implying that it also matches the type of the trait decl feels like it could go ICEy in error scenarios (the ConstArgHasType inside confirm_impl_candidate checks the type on the impl, not the trait). Is prooobably fine though?

I'll yeet it for now and then when you rereview and see this comment you can decide~

@BoxyUwU

BoxyUwU commented Aug 28, 2026

Copy link
Copy Markdown
Member

@bors r+

this check isn't soundness critical so worst case it's fine :3

@rust-bors

rust-bors Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

📌 Commit d471202 has been approved by BoxyUwU

It is now in the queue for this repository.

@rust-bors rust-bors Bot 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 28, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 28, 2026
…er_types, r=BoxyUwU

fix ICE in generic_const_parameter_types with inherents

tracking issue: rust-lang#137626

relevant PR where the code was added: rust-lang#154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

- `normalize_canonicalized_inherent_projection` is called with `AliasTermKind::InherentConst` with the generic args being in "self form", i.e. `[ThreeTypes<u8, u16, u32>]`
- `traits::normalize_inherent_projection` is called with said alias
  - it calls `compute_inherent_assoc_term_args`, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. `[u8, u16, u32]`
  - it then calls `const_of_item` and instantiates with `[u8, u16, u32]`. this is correct and good, `const_of_item` expects "impl form" args.
  - it then calls `push_const_arg_has_type_obligation`
    - which calls `type_of` and instantiates with `[u8, u16, u32]` to fetch the type of the const, to be able to register a `ConstArgHasType`. this is correct and good, `type_of` expects "impl form" args.
  - `traits::normalize_inherent_projection` returns, dropping the impl form args it computed
- `normalize_canonicalized_inherent_projection` calls `ocx.register_obligations(const_arg_has_type_obligation(...))`, passing `goal`. Remember that `goal` has the original "self args" generic arg format.
  - `const_arg_has_type_obligation` calls `type_of` and instantiates with `[ThreeTypes<u8, u16, u32>]`. This is no good very bad!! `type_of` expects "impl form" args, not "self form"!!
  - ICE!! `type parameter T3/rust-lang#2 (T3/rust-lang#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]`

The reason I filed this under `feature(generic_const_parameter_types)` is because for this bug to manifest, `type_of` must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

`normalize_inherent_projection` already registers a `ConstArgHasType`. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 28, 2026
…er_types, r=BoxyUwU

fix ICE in generic_const_parameter_types with inherents

tracking issue: rust-lang#137626

relevant PR where the code was added: rust-lang#154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

- `normalize_canonicalized_inherent_projection` is called with `AliasTermKind::InherentConst` with the generic args being in "self form", i.e. `[ThreeTypes<u8, u16, u32>]`
- `traits::normalize_inherent_projection` is called with said alias
  - it calls `compute_inherent_assoc_term_args`, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. `[u8, u16, u32]`
  - it then calls `const_of_item` and instantiates with `[u8, u16, u32]`. this is correct and good, `const_of_item` expects "impl form" args.
  - it then calls `push_const_arg_has_type_obligation`
    - which calls `type_of` and instantiates with `[u8, u16, u32]` to fetch the type of the const, to be able to register a `ConstArgHasType`. this is correct and good, `type_of` expects "impl form" args.
  - `traits::normalize_inherent_projection` returns, dropping the impl form args it computed
- `normalize_canonicalized_inherent_projection` calls `ocx.register_obligations(const_arg_has_type_obligation(...))`, passing `goal`. Remember that `goal` has the original "self args" generic arg format.
  - `const_arg_has_type_obligation` calls `type_of` and instantiates with `[ThreeTypes<u8, u16, u32>]`. This is no good very bad!! `type_of` expects "impl form" args, not "self form"!!
  - ICE!! `type parameter T3/rust-lang#2 (T3/rust-lang#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]`

The reason I filed this under `feature(generic_const_parameter_types)` is because for this bug to manifest, `type_of` must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

`normalize_inherent_projection` already registers a `ConstArgHasType`. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 28, 2026
…er_types, r=BoxyUwU

fix ICE in generic_const_parameter_types with inherents

tracking issue: rust-lang#137626

relevant PR where the code was added: rust-lang#154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

- `normalize_canonicalized_inherent_projection` is called with `AliasTermKind::InherentConst` with the generic args being in "self form", i.e. `[ThreeTypes<u8, u16, u32>]`
- `traits::normalize_inherent_projection` is called with said alias
  - it calls `compute_inherent_assoc_term_args`, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. `[u8, u16, u32]`
  - it then calls `const_of_item` and instantiates with `[u8, u16, u32]`. this is correct and good, `const_of_item` expects "impl form" args.
  - it then calls `push_const_arg_has_type_obligation`
    - which calls `type_of` and instantiates with `[u8, u16, u32]` to fetch the type of the const, to be able to register a `ConstArgHasType`. this is correct and good, `type_of` expects "impl form" args.
  - `traits::normalize_inherent_projection` returns, dropping the impl form args it computed
- `normalize_canonicalized_inherent_projection` calls `ocx.register_obligations(const_arg_has_type_obligation(...))`, passing `goal`. Remember that `goal` has the original "self args" generic arg format.
  - `const_arg_has_type_obligation` calls `type_of` and instantiates with `[ThreeTypes<u8, u16, u32>]`. This is no good very bad!! `type_of` expects "impl form" args, not "self form"!!
  - ICE!! `type parameter T3/rust-lang#2 (T3/rust-lang#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]`

The reason I filed this under `feature(generic_const_parameter_types)` is because for this bug to manifest, `type_of` must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

`normalize_inherent_projection` already registers a `ConstArgHasType`. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU
rust-bors Bot pushed a commit that referenced this pull request Aug 28, 2026
…uwer

Rollup of 15 pull requests

Successful merges:

 - #160170 (Refactored docs for `std::fs::set_permissions_nofollow` + fix BSD-based systems to use fchmodat with AT_SYMLINK_NOFOLLOW flag)
 - #160594 (attach global target features to module-level assembly)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161353 (Add test for parallel compiler reproducible build)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 28, 2026
…er_types, r=BoxyUwU

fix ICE in generic_const_parameter_types with inherents

tracking issue: rust-lang#137626

relevant PR where the code was added: rust-lang#154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

- `normalize_canonicalized_inherent_projection` is called with `AliasTermKind::InherentConst` with the generic args being in "self form", i.e. `[ThreeTypes<u8, u16, u32>]`
- `traits::normalize_inherent_projection` is called with said alias
  - it calls `compute_inherent_assoc_term_args`, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. `[u8, u16, u32]`
  - it then calls `const_of_item` and instantiates with `[u8, u16, u32]`. this is correct and good, `const_of_item` expects "impl form" args.
  - it then calls `push_const_arg_has_type_obligation`
    - which calls `type_of` and instantiates with `[u8, u16, u32]` to fetch the type of the const, to be able to register a `ConstArgHasType`. this is correct and good, `type_of` expects "impl form" args.
  - `traits::normalize_inherent_projection` returns, dropping the impl form args it computed
- `normalize_canonicalized_inherent_projection` calls `ocx.register_obligations(const_arg_has_type_obligation(...))`, passing `goal`. Remember that `goal` has the original "self args" generic arg format.
  - `const_arg_has_type_obligation` calls `type_of` and instantiates with `[ThreeTypes<u8, u16, u32>]`. This is no good very bad!! `type_of` expects "impl form" args, not "self form"!!
  - ICE!! `type parameter T3/rust-lang#2 (T3/rust-lang#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]`

The reason I filed this under `feature(generic_const_parameter_types)` is because for this bug to manifest, `type_of` must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

`normalize_inherent_projection` already registers a `ConstArgHasType`. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU
rust-bors Bot pushed a commit that referenced this pull request Aug 28, 2026
…uwer

Rollup of 16 pull requests

Successful merges:

 - #160170 (Refactored docs for `std::fs::set_permissions_nofollow` + fix BSD-based systems to use fchmodat with AT_SYMLINK_NOFOLLOW flag)
 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Aug 28, 2026
…er_types, r=BoxyUwU

fix ICE in generic_const_parameter_types with inherents

tracking issue: rust-lang#137626

relevant PR where the code was added: rust-lang#154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

- `normalize_canonicalized_inherent_projection` is called with `AliasTermKind::InherentConst` with the generic args being in "self form", i.e. `[ThreeTypes<u8, u16, u32>]`
- `traits::normalize_inherent_projection` is called with said alias
  - it calls `compute_inherent_assoc_term_args`, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. `[u8, u16, u32]`
  - it then calls `const_of_item` and instantiates with `[u8, u16, u32]`. this is correct and good, `const_of_item` expects "impl form" args.
  - it then calls `push_const_arg_has_type_obligation`
    - which calls `type_of` and instantiates with `[u8, u16, u32]` to fetch the type of the const, to be able to register a `ConstArgHasType`. this is correct and good, `type_of` expects "impl form" args.
  - `traits::normalize_inherent_projection` returns, dropping the impl form args it computed
- `normalize_canonicalized_inherent_projection` calls `ocx.register_obligations(const_arg_has_type_obligation(...))`, passing `goal`. Remember that `goal` has the original "self args" generic arg format.
  - `const_arg_has_type_obligation` calls `type_of` and instantiates with `[ThreeTypes<u8, u16, u32>]`. This is no good very bad!! `type_of` expects "impl form" args, not "self form"!!
  - ICE!! `type parameter T3/rust-lang#2 (T3/rust-lang#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]`

The reason I filed this under `feature(generic_const_parameter_types)` is because for this bug to manifest, `type_of` must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

`normalize_inherent_projection` already registers a `ConstArgHasType`. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
…uwer

Rollup of 16 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161702 (Use `drop_guard` in some places in {core,alloc,std})
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
Zalathar added a commit to Zalathar/rust that referenced this pull request Aug 29, 2026
…er_types, r=BoxyUwU

fix ICE in generic_const_parameter_types with inherents

tracking issue: rust-lang#137626

relevant PR where the code was added: rust-lang#154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

- `normalize_canonicalized_inherent_projection` is called with `AliasTermKind::InherentConst` with the generic args being in "self form", i.e. `[ThreeTypes<u8, u16, u32>]`
- `traits::normalize_inherent_projection` is called with said alias
  - it calls `compute_inherent_assoc_term_args`, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. `[u8, u16, u32]`
  - it then calls `const_of_item` and instantiates with `[u8, u16, u32]`. this is correct and good, `const_of_item` expects "impl form" args.
  - it then calls `push_const_arg_has_type_obligation`
    - which calls `type_of` and instantiates with `[u8, u16, u32]` to fetch the type of the const, to be able to register a `ConstArgHasType`. this is correct and good, `type_of` expects "impl form" args.
  - `traits::normalize_inherent_projection` returns, dropping the impl form args it computed
- `normalize_canonicalized_inherent_projection` calls `ocx.register_obligations(const_arg_has_type_obligation(...))`, passing `goal`. Remember that `goal` has the original "self args" generic arg format.
  - `const_arg_has_type_obligation` calls `type_of` and instantiates with `[ThreeTypes<u8, u16, u32>]`. This is no good very bad!! `type_of` expects "impl form" args, not "self form"!!
  - ICE!! `type parameter T3/rust-lang#2 (T3/rust-lang#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]`

The reason I filed this under `feature(generic_const_parameter_types)` is because for this bug to manifest, `type_of` must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

`normalize_inherent_projection` already registers a `ConstArgHasType`. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup of 17 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
 - #161924 (Windows: document that `normalize_lexically` converts `/` to `\`)
 - #161927 (Change `rustc_middle/src/hooks/mod.rs` to `hooks.rs`)
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup of 17 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
 - #161924 (Windows: document that `normalize_lexically` converts `/` to `\`)
 - #161927 (Change `rustc_middle/src/hooks/mod.rs` to `hooks.rs`)
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup of 17 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161888 (compiler: Allow safestack to be togglable via #[sanitize(safestack = "...")])
 - #161897 (Reject contract attributes without arguments)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
 - #161924 (Windows: document that `normalize_lexically` converts `/` to `\`)
 - #161927 (Change `rustc_middle/src/hooks/mod.rs` to `hooks.rs`)
@rust-bors
rust-bors Bot merged commit 1a002cf into rust-lang:main Aug 29, 2026
13 checks passed
@rustbot rustbot added this to the 1.100.0 milestone Aug 29, 2026
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup merge of #161858 - khyperia:ice-generic_const_parameter_types, r=BoxyUwU

fix ICE in generic_const_parameter_types with inherents

tracking issue: #137626

relevant PR where the code was added: #154853 (fyi ping @lapla-cogito - nws that this was buggy, it's extreeeemely subtle and easy to miss! ❤️ I mean, I also reviewed that PR and missed it too :3 )

discovered when implementing a change that explicitly tracks whether the args for inherent associated consts are in "self form" or "impl form"

Following along the test case:

- `normalize_canonicalized_inherent_projection` is called with `AliasTermKind::InherentConst` with the generic args being in "self form", i.e. `[ThreeTypes<u8, u16, u32>]`
- `traits::normalize_inherent_projection` is called with said alias
  - it calls `compute_inherent_assoc_term_args`, which does the dance of generating fresh vars for each param in the impl block, equating with the self type, and returning what the fresh vars solved to. This converts from "self args" to "impl args", i.e. `[u8, u16, u32]`
  - it then calls `const_of_item` and instantiates with `[u8, u16, u32]`. this is correct and good, `const_of_item` expects "impl form" args.
  - it then calls `push_const_arg_has_type_obligation`
    - which calls `type_of` and instantiates with `[u8, u16, u32]` to fetch the type of the const, to be able to register a `ConstArgHasType`. this is correct and good, `type_of` expects "impl form" args.
  - `traits::normalize_inherent_projection` returns, dropping the impl form args it computed
- `normalize_canonicalized_inherent_projection` calls `ocx.register_obligations(const_arg_has_type_obligation(...))`, passing `goal`. Remember that `goal` has the original "self args" generic arg format.
  - `const_arg_has_type_obligation` calls `type_of` and instantiates with `[ThreeTypes<u8, u16, u32>]`. This is no good very bad!! `type_of` expects "impl form" args, not "self form"!!
  - ICE!! `type parameter T3/#2 (T3/#2/2) out of range when instantiating, args=[ThreeTypes<u8, u16, u32>]`

The reason I filed this under `feature(generic_const_parameter_types)` is because for this bug to manifest, `type_of` must return a type that actually references a generic param to be able to trigger an ICE. Otherwise, the buggy incorrect args are silently ignored and compilation continues "fine".

The fix:

`normalize_inherent_projection` already registers a `ConstArgHasType`. why are we doing it a second time. just delete it. 💀

r? @BoxyUwU
@khyperia
khyperia deleted the ice-generic_const_parameter_types branch August 29, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants