Skip to content

Commit 4cadb5d

Browse files
authored
Rollup merge of rust-lang#135464 - lukas-code:project-infinite-to-error, r=FedericoBruzzone,oli-obk
fix ICE with references to infinite structs in consts fixes rust-lang#114484 Normalizing `<Type as Pointee>::Metadata` may emit a (non-fatal) error during trait selection if finding the struct tail of `Type` hits the recursion limit. When this happens, prior this PR, we would treat the projection as rigid, i.e. don't normalize it further. This PR changes it so that we normalize to `ty::Error` instead. This is important, because to compute the layout of `&Type` we need to compute the layout of `<Type as Pointee>::Metadata` https://github.com/rust-lang/rust/blob/2ae9916816a448fcaab3b2da461de754eda0055a/compiler/rustc_ty_utils/src/layout.rs#L247-L273 and computing the layout of a rigid alias will (correctly) fail and needs to report an error to the user. For example: ```rust trait Project { type Assoc; } fn foo<T: Project>() { [(); { let _: Option<T::Assoc> = None; // ^^^^^^^^ this projection is rigid, so we can't know it's layout 0 }]; } ``` ``` error: constant expression depends on a generic parameter --> src/lib.rs:6:10 | 6 | [(); { | __________^ 7 | | let _: Option<T::Assoc> = None; 8 | | // ^^^^^^^^ this projection is rigid, so we can't know it's layout 9 | | 0 10 | | }]; | |_____^ | = note: this may fail depending on what value the parameter takes ``` For non-generic rigid projections we will currently ICE, because we incorrectly assume that `LayoutError::Unknown` means that a const must be generic (rust-lang#135138). This is being fixed and turned into a proper error in rust-lang#135158. ```rust #![feature(trivial_bounds)] trait Project { type Assoc; } fn foo() where u8: Project, { [(); { let _: Option<<u8 as Project>::Assoc> = None; // ICEs currently, but will be an error 0 }]; } ``` However, if we hit the recursion limit when normalizing `<Type as Pointee>::Metadata` we don't want to report a layout error, because we already emitted the recursion error. So by normalizing to `ty::Error` here, we get a `LayoutError::ReferencesError` instead of a `LayoutError::Unknown` and don't report the layout error to the user.
2 parents 62f2c3c + 7a3c4f7 commit 4cadb5d

5 files changed

+111
-6
lines changed

Diff for: compiler/rustc_trait_selection/src/traits/project.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,9 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
11481148
// If returned by `struct_tail` this is the empty tuple.
11491149
| ty::Tuple(..)
11501150
// Integers and floats are always Sized, and so have unit type metadata.
1151-
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
1151+
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..))
1152+
// This happens if we reach the recursion limit when finding the struct tail.
1153+
| ty::Error(..) => true,
11521154

11531155
// We normalize from `Wrapper<Tail>::Metadata` to `Tail::Metadata` if able.
11541156
// Otherwise, type parameters, opaques, and unnormalized projections have
@@ -1179,8 +1181,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
11791181
| ty::Alias(..)
11801182
| ty::Bound(..)
11811183
| ty::Placeholder(..)
1182-
| ty::Infer(..)
1183-
| ty::Error(_) => {
1184+
| ty::Infer(..) => {
11841185
if tail.has_infer_types() {
11851186
candidate_set.mark_ambiguous();
11861187
}

Diff for: tests/crashes/114484.rs renamed to tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
//@ known-bug: #114484
1+
//@ build-fail
2+
3+
//@ error-pattern: reached the recursion limit while instantiating
4+
//@ error-pattern: reached the recursion limit finding the struct tail
5+
6+
// Regression test for #114484: This used to ICE during monomorphization, because we treated
7+
// `<VirtualWrapper<...> as Pointee>::Metadata` as a rigid projection after reaching the recursion
8+
// limit when finding the struct tail.
9+
210
use std::marker::PhantomData;
311

412
trait MyTrait {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
error: reached the recursion limit finding the struct tail for `[u8; 256]`
2+
|
3+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
4+
5+
error: reached the recursion limit finding the struct tail for `[u8; 256]`
6+
|
7+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
8+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
9+
10+
error: reached the recursion limit finding the struct tail for `[u8; 256]`
11+
|
12+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
13+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
14+
15+
error: reached the recursion limit finding the struct tail for `[u8; 256]`
16+
|
17+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
18+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
19+
20+
note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
21+
--> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
22+
|
23+
LL | unsafe { virtualize_my_trait(L, self) }
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
26+
error: reached the recursion limit finding the struct tail for `SomeData<256>`
27+
|
28+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
29+
30+
error: reached the recursion limit finding the struct tail for `SomeData<256>`
31+
|
32+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
33+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
34+
35+
error: reached the recursion limit finding the struct tail for `SomeData<256>`
36+
|
37+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
38+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
39+
40+
error: reached the recursion limit finding the struct tail for `SomeData<256>`
41+
|
42+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
43+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
44+
45+
note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
46+
--> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
47+
|
48+
LL | unsafe { virtualize_my_trait(L, self) }
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50+
51+
error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
52+
|
53+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
54+
55+
error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
56+
|
57+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
58+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
59+
60+
error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
61+
|
62+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
63+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
64+
65+
error: reached the recursion limit finding the struct tail for `VirtualWrapper<SomeData<256>, 0>`
66+
|
67+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
68+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
69+
70+
note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
71+
--> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
72+
|
73+
LL | unsafe { virtualize_my_trait(L, self) }
74+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
75+
76+
error: reached the recursion limit while instantiating `<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<..., 1>, 1>, 1>, 1>, 1> as MyTrait>::virtualize`
77+
|
78+
note: `<VirtualWrapper<T, L> as MyTrait>::virtualize` defined here
79+
--> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:5
80+
|
81+
LL | fn virtualize(&self) -> &dyn MyTrait {
82+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
83+
= note: the full type name has been written to '$TEST_BUILD_DIR/infinite/infinite-instantiation-struct-tail-ice-114484/infinite-instantiation-struct-tail-ice-114484.long-type.txt'
84+
85+
error: aborting due to 13 previous errors
86+

Diff for: tests/ui/structs/ice-struct-tail-normalization-113272.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ struct Other {
1313
fn main() {
1414
unsafe {
1515
std::mem::transmute::<Option<()>, Option<&Other>>(None);
16+
//~^ ERROR cannot transmute
1617
}
1718
}

Diff for: tests/ui/structs/ice-struct-tail-normalization-113272.stderr

+11-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@ LL | type RefTarget;
1313
LL | impl Trait for () where Missing: Trait {}
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `RefTarget` in implementation
1515

16-
error: aborting due to 2 previous errors
16+
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
17+
--> $DIR/ice-struct-tail-normalization-113272.rs:15:9
18+
|
19+
LL | std::mem::transmute::<Option<()>, Option<&Other>>(None);
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
|
22+
= note: source type: `Option<()>` (8 bits)
23+
= note: target type: `Option<&Other>` (unable to determine layout for `Other` because `<() as Trait>::RefTarget` cannot be normalized)
24+
25+
error: aborting due to 3 previous errors
1726

18-
Some errors have detailed explanations: E0046, E0412.
27+
Some errors have detailed explanations: E0046, E0412, E0512.
1928
For more information about an error, try `rustc --explain E0046`.

0 commit comments

Comments
 (0)