Skip to content

Commit 023d36e

Browse files
committed
Auto merge of #157562 - sjwang05:fix-138660-enum-discr-layout, r=<try>
Avoid computing layout of enums with non-int discriminants
2 parents 61d7280 + 183e882 commit 023d36e

4 files changed

Lines changed: 57 additions & 7 deletions

File tree

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,17 @@ 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 Err(guar) = def.eval_explicit_discr(tcx, def_id)
715+
{
716+
return Err(error(cx, LayoutError::ReferencesError(guar)));
717+
}
718+
}
719+
}
720+
710721
let discriminants_iter = || {
711722
def.is_enum()
712723
.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/issue-138660-non-int-discriminant-promoted-ice.rs:11: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/issue-138660-non-int-discriminant-promoted-ice.rs:13: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/issue-138660-non-int-discriminant-promoted-ice.rs:9: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`.

0 commit comments

Comments
 (0)