Skip to content

Commit 4b02d64

Browse files
authored
Rollup merge of #131909 - clubby789:enum-overflow-cast, r=compiler-errors
Prevent overflowing enum cast from ICEing Fixes #131902
2 parents 4c0bab3 + ab4222a commit 4b02d64

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

compiler/rustc_mir_build/src/thir/cx/expr.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,14 @@ impl<'tcx> Cx<'tcx> {
281281
.unwrap_or_else(|e| panic!("could not compute layout for {param_env_ty:?}: {e:?}"))
282282
.size;
283283

284-
let lit = ScalarInt::try_from_uint(discr_offset as u128, size).unwrap();
284+
let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size);
285+
if overflowing {
286+
// An erroneous enum with too many variants for its repr will emit E0081 and E0370
287+
self.tcx.dcx().span_delayed_bug(
288+
source.span,
289+
"overflowing enum wasn't rejected by hir analysis",
290+
);
291+
}
285292
let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
286293
let offset = self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind });
287294

tests/ui/error-codes/E0081.rs

+42
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,47 @@ enum MultipleDuplicates {
5050
//~^ NOTE `-2` assigned here
5151
}
5252

53+
// Test for #131902
54+
// Ensure that casting an enum with too many variants for its repr
55+
// does not ICE
56+
#[repr(u8)]
57+
enum TooManyVariants {
58+
//~^ ERROR discriminant value `0` assigned more than once
59+
X000, X001, X002, X003, X004, X005, X006, X007, X008, X009,
60+
//~^ NOTE `0` assigned here
61+
//~| NOTE discriminant for `X256` incremented from this startpoint
62+
X010, X011, X012, X013, X014, X015, X016, X017, X018, X019,
63+
X020, X021, X022, X023, X024, X025, X026, X027, X028, X029,
64+
X030, X031, X032, X033, X034, X035, X036, X037, X038, X039,
65+
X040, X041, X042, X043, X044, X045, X046, X047, X048, X049,
66+
X050, X051, X052, X053, X054, X055, X056, X057, X058, X059,
67+
X060, X061, X062, X063, X064, X065, X066, X067, X068, X069,
68+
X070, X071, X072, X073, X074, X075, X076, X077, X078, X079,
69+
X080, X081, X082, X083, X084, X085, X086, X087, X088, X089,
70+
X090, X091, X092, X093, X094, X095, X096, X097, X098, X099,
71+
X100, X101, X102, X103, X104, X105, X106, X107, X108, X109,
72+
X110, X111, X112, X113, X114, X115, X116, X117, X118, X119,
73+
X120, X121, X122, X123, X124, X125, X126, X127, X128, X129,
74+
X130, X131, X132, X133, X134, X135, X136, X137, X138, X139,
75+
X140, X141, X142, X143, X144, X145, X146, X147, X148, X149,
76+
X150, X151, X152, X153, X154, X155, X156, X157, X158, X159,
77+
X160, X161, X162, X163, X164, X165, X166, X167, X168, X169,
78+
X170, X171, X172, X173, X174, X175, X176, X177, X178, X179,
79+
X180, X181, X182, X183, X184, X185, X186, X187, X188, X189,
80+
X190, X191, X192, X193, X194, X195, X196, X197, X198, X199,
81+
X200, X201, X202, X203, X204, X205, X206, X207, X208, X209,
82+
X210, X211, X212, X213, X214, X215, X216, X217, X218, X219,
83+
X220, X221, X222, X223, X224, X225, X226, X227, X228, X229,
84+
X230, X231, X232, X233, X234, X235, X236, X237, X238, X239,
85+
X240, X241, X242, X243, X244, X245, X246, X247, X248, X249,
86+
X250, X251, X252, X253, X254, X255,
87+
X256,
88+
//~^ ERROR enum discriminant overflowed
89+
//~| NOTE overflowed on value after 255
90+
//~| NOTE explicitly set `X256 = 0`
91+
//~| NOTE `0` assigned here
92+
}
93+
5394
fn main() {
95+
TooManyVariants::X256 as u8;
5496
}

tests/ui/error-codes/E0081.stderr

+26-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,30 @@ LL |
7373
LL | V9,
7474
| -- `-2` assigned here
7575

76-
error: aborting due to 5 previous errors
76+
error[E0370]: enum discriminant overflowed
77+
--> $DIR/E0081.rs:87:5
78+
|
79+
LL | X256,
80+
| ^^^^ overflowed on value after 255
81+
|
82+
= note: explicitly set `X256 = 0` if that is desired outcome
83+
84+
error[E0081]: discriminant value `0` assigned more than once
85+
--> $DIR/E0081.rs:57:1
86+
|
87+
LL | enum TooManyVariants {
88+
| ^^^^^^^^^^^^^^^^^^^^
89+
LL |
90+
LL | X000, X001, X002, X003, X004, X005, X006, X007, X008, X009,
91+
| ----
92+
| |
93+
| `0` assigned here
94+
| discriminant for `X256` incremented from this startpoint (`X000` + 256 variants later => `X256` = 0)
95+
...
96+
LL | X256,
97+
| ---- `0` assigned here
98+
99+
error: aborting due to 7 previous errors
77100

78-
For more information about this error, try `rustc --explain E0081`.
101+
Some errors have detailed explanations: E0081, E0370.
102+
For more information about an error, try `rustc --explain E0081`.

0 commit comments

Comments
 (0)