Skip to content

Commit 9185582

Browse files
Rollup merge of rust-lang#161858 - khyperia:ice-generic_const_parameter_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
2 parents 6a87718 + d471202 commit 9185582

2 files changed

Lines changed: 22 additions & 12 deletions

File tree

compiler/rustc_traits/src/normalize_projection_ty.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,6 @@ fn normalize_canonicalized_projection<'tcx>(
5959
0,
6060
&mut obligations,
6161
);
62-
obligations.extend(const_arg_has_type_obligation(
63-
tcx,
64-
param_env,
65-
normalized_term,
66-
goal,
67-
));
6862
ocx.register_obligations(obligations);
6963
// #112047: With projections and opaques, we are able to create opaques that
7064
// are recursive (given some generic parameters of the opaque's type variables).
@@ -147,12 +141,6 @@ fn normalize_canonicalized_inherent_projection<'tcx>(
147141
0,
148142
&mut obligations,
149143
);
150-
obligations.extend(const_arg_has_type_obligation(
151-
tcx,
152-
param_env,
153-
normalized_term,
154-
goal,
155-
));
156144
ocx.register_obligations(obligations);
157145

158146
Ok(NormalizationResult { normalized_term })
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ check-pass
2+
#![feature(
3+
min_generic_const_args,
4+
generic_const_parameter_types,
5+
inherent_associated_types,
6+
min_adt_const_params,
7+
const_param_ty_trait
8+
)]
9+
10+
struct ThreeTypes<T1, T2, T3>(T1, T2, T3);
11+
12+
impl<T1, T2, T3: std::marker::ConstParamTy_> ThreeTypes<T1, T2, T3> {
13+
type const INHERENT: [T3; 0] = [];
14+
}
15+
16+
struct Struct<const O: [u32; 0]>;
17+
18+
fn f() -> Struct<{ core::direct_const_arg!(ThreeTypes::<u8, u16, u32>::INHERENT) }> {
19+
Struct
20+
}
21+
22+
fn main() {}

0 commit comments

Comments
 (0)