forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#137399 - lukas-code:oopsie-woopsie, r=compi…
…ler-errors fix ICE in layout computation with unnormalizable const The first commit reverts half of 7a667d2, where I removed a case from `layout_of` for handling non-generic unevaluated consts in array length, that I incorrectly assumed to be unreachable. This can actually happen with the combination of `feature(generic_const_exprs)` and `feature(trivial_bounds)`, because GCE makes anon consts inherit their parent's predicates and with an impossible predicate like `u8: A` it's possible to have an array whose length is an associated const like `<u8 as A>::B` that is not generic, but also can't be normalized: ```rust #![feature(generic_const_exprs)] #![feature(trivial_bounds)] trait A { const B: usize; } // With GCE + trivial bounds this definition is not a compile error. // Computing the layout of this type shouldn't ICE. struct S([u8; <u8 as A>::B]) where u8: A; ``` --- The first commit also incidentally fixes rust-lang#137308, which also managed to get an unnormalizable assoc const into an array length: ```rust trait A { const B: usize; } impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained const B: usize = 42; } // Computing the layout of this type shouldn't ICE, even with the compile error above. struct S([u8; <u8 as A>::B]); ``` This happens, because we bail out from `codegen_select_candidate` with an error if the selected impl has unconstrained params to avoid leaking infer vars out of a query. `Instance::try_resolve` will then return `Ok(None)`, which for assoc consts roughly means "this const can't be evaluated in a generic context" and is treated as such: https://github.com/rust-lang/rust/blob/71e06b9c59d6af50fdc55aed75620493d29baf98/compiler/rustc_middle/src/mir/interpret/queries.rs#L84 (and this can ICE if the const isn't generic: rust-lang#135617). However, here `<u8 as A>::B` is definitely not "too generic" and also not unresolvable due to an unsatisfiable `u8: A` bound, so I've included the second commit to change the result of `Instance::try_resolve` from `Ok(None)` to `Err(ErrorGuaranteed)` when resolving an assoc item to an impl with unconstrained generic params. This has the effect that `<u8 as A>::B` will now be normalized to `ConstKind::Error` in the example above. This properly fixes rust-lang#137308, by no longer treating `<u8 as A>::B` as unresolvable even though it clearly has a unique impl that it resolves to. It also has the effect of changing the layout error from `Unknown` ("the type may be valid but has no sensible layout") to `ReferencesError` ("a non-layout error is reported elsewhere") which seems more appropriate. r? ```@compiler-errors```
- Loading branch information
Showing
8 changed files
with
103 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//! With `feature(generic_const_exprs)`, anon consts (e.g. length in array types) will | ||
//! inherit their parent's predicates. When combined with `feature(trivial_bounds)`, it | ||
//! is possible to have an unevaluated constant that is rigid, but not generic. | ||
//! | ||
//! This is what happens below: `u8: A` does not hold in the global environment, but | ||
//! with trivial bounds + GCE it it possible that `<u8 as A>::B` can appear in an array | ||
//! length without causing a compile error. This constant is *rigid* (i.e. it cannot be | ||
//! normalized further), but it is *not generic* (i.e. it does not depend on any generic | ||
//! parameters). | ||
//! | ||
//! This test ensures that we do not ICE in layout computation when encountering such a | ||
//! constant. | ||
#![feature(rustc_attrs)] | ||
#![feature(generic_const_exprs)] //~ WARNING: the feature `generic_const_exprs` is incomplete | ||
#![feature(trivial_bounds)] | ||
|
||
#![crate_type = "lib"] | ||
|
||
trait A { | ||
const B: usize; | ||
} | ||
|
||
#[rustc_layout(debug)] | ||
struct S([u8; <u8 as A>::B]) //~ ERROR: the type `[u8; <u8 as A>::B]` has an unknown layout | ||
where | ||
u8: A; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes | ||
--> $DIR/gce-rigid-const-in-array-len.rs:15:12 | ||
| | ||
LL | #![feature(generic_const_exprs)] | ||
| ^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information | ||
= note: `#[warn(incomplete_features)]` on by default | ||
|
||
error: the type `[u8; <u8 as A>::B]` has an unknown layout | ||
--> $DIR/gce-rigid-const-in-array-len.rs:25:1 | ||
| | ||
LL | struct S([u8; <u8 as A>::B]) | ||
| ^^^^^^^^ | ||
|
||
error: aborting due to 1 previous error; 1 warning emitted | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//! Regression test for <https://github.com/rust-lang/rust/issues/137308>. | ||
//! | ||
//! This used to ICE in layout computation, because `<u8 as A>::B` fails to normalize | ||
//! due to the unconstrained param on the impl. | ||
#![feature(rustc_attrs)] | ||
#![crate_type = "lib"] | ||
|
||
trait A { | ||
const B: usize; | ||
} | ||
|
||
impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained | ||
const B: usize = 42; | ||
} | ||
|
||
#[rustc_layout(debug)] | ||
struct S([u8; <u8 as A>::B]); //~ ERROR: the type has an unknown layout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates | ||
--> $DIR/unconstrained-param-ice-137308.rs:13:6 | ||
| | ||
LL | impl<C: ?Sized> A for u8 { | ||
| ^ unconstrained type parameter | ||
|
||
error: the type has an unknown layout | ||
--> $DIR/unconstrained-param-ice-137308.rs:18:1 | ||
| | ||
LL | struct S([u8; <u8 as A>::B]); | ||
| ^^^^^^^^ | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0207`. |