Skip to content

Commit 88d314a

Browse files
committed
typeck enum discrs before attempting to compute layout
1 parent 8954863 commit 88d314a

5 files changed

Lines changed: 66 additions & 7 deletions

File tree

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,18 @@ fn layout_of_uncached<'tcx>(
707707
let discr_range_of_repr =
708708
|min, max| abi::Integer::discr_range_of_repr(tcx, ty, &def.repr(), min, max);
709709

710+
// We shouldn't be computing the layout of discrs that fail typeck
711+
if def.is_enum() {
712+
for v in def.variants() {
713+
if let ty::VariantDiscr::Explicit(def_id) = v.discr
714+
&& let Some(local_did) = def_id.as_local()
715+
&& let Some(guar) = tcx.typeck(local_did).tainted_by_errors
716+
{
717+
return Err(error(cx, LayoutError::ReferencesError(guar)));
718+
}
719+
}
720+
}
721+
710722
let discriminants_iter = || {
711723
def.is_enum()
712724
.then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))

tests/crashes/138660.rs

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Previously, enums with non-int discrs ICEd during CTFE of promoteds.
2+
3+
enum A {
4+
//~^ ERROR `#[repr(inttype)]` must be specified
5+
V1(isize) = 1..=10,
6+
//~^ ERROR mismatched types
7+
V0 = 1..=10,
8+
//~^ ERROR mismatched types
9+
}
10+
11+
const B: &'static [A] = &[A::V0, A::V1(111)];
12+
13+
fn main() {}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/non-int-discriminant-promoted-ice-138660.rs:5:17
3+
|
4+
LL | V1(isize) = 1..=10,
5+
| ^^^^^^ expected `isize`, found `RangeInclusive<{integer}>`
6+
|
7+
= note: expected type `isize`
8+
found struct `std::ops::RangeInclusive<{integer}>`
9+
= note: enum variant discriminant can only be of a primitive type compatible with the enum's `repr`
10+
11+
error[E0308]: mismatched types
12+
--> $DIR/non-int-discriminant-promoted-ice-138660.rs:7:10
13+
|
14+
LL | V0 = 1..=10,
15+
| ^^^^^^ expected `isize`, found `RangeInclusive<{integer}>`
16+
|
17+
= note: expected type `isize`
18+
found struct `std::ops::RangeInclusive<{integer}>`
19+
= note: enum variant discriminant can only be of a primitive type compatible with the enum's `repr`
20+
21+
error[E0732]: `#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants
22+
--> $DIR/non-int-discriminant-promoted-ice-138660.rs:3:1
23+
|
24+
LL | enum A {
25+
| ^^^^^^
26+
LL |
27+
LL | V1(isize) = 1..=10,
28+
| ------ explicit discriminant on non-unit variant specified here
29+
30+
error: aborting due to 3 previous errors
31+
32+
Some errors have detailed explanations: E0308, E0732.
33+
For more information about an error, try `rustc --explain E0308`.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ check-pass
2+
// Ensure that `size_of::<Thing>()` as a discriminant does not cause a cycle error.
3+
4+
enum Thing {
5+
Variant = size_of::<Thing>() as isize,
6+
}
7+
8+
fn main() {}

0 commit comments

Comments
 (0)