Skip to content

Commit 43265f5

Browse files
authored
Rollup merge of #124504 - gurry:123710-union-ICE, r=oli-obk
Mark unions non-const-propagatable in `KnownPanicsLint` without calling layout Fixes #123710 The ICE occurs during the layout calculation of the union `InvalidTag` in #123710 because the following assert fails:https://github.com/rust-lang/rust/blob/5fe8b697e729b6eb64841a3905e57da1b47f4ca3/compiler/rustc_abi/src/layout.rs#L289-L292 The layout calculation is invoked by `KnownPanicsLint` when it is trying to figure out which locals it can const prop. Since `KnownPanicsLint` is never actually going to const props unions thanks to PR #121628 there's no point calling layout to check if it can. So in this fix I skip the call to layout and just mark the local non-const propagatable if it is a union.
2 parents 0580588 + 254a9fb commit 43265f5

File tree

4 files changed

+64
-24
lines changed

4 files changed

+64
-24
lines changed

compiler/rustc_mir_transform/src/known_panics_lint.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -896,13 +896,19 @@ impl CanConstProp {
896896
};
897897
for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
898898
let ty = body.local_decls[local].ty;
899-
match tcx.layout_of(param_env.and(ty)) {
900-
Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
901-
// Either the layout fails to compute, then we can't use this local anyway
902-
// or the local is too large, then we don't want to.
903-
_ => {
904-
*val = ConstPropMode::NoPropagation;
905-
continue;
899+
if ty.is_union() {
900+
// Do not const prop unions as they can
901+
// ICE during layout calc
902+
*val = ConstPropMode::NoPropagation;
903+
} else {
904+
match tcx.layout_of(param_env.and(ty)) {
905+
Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
906+
// Either the layout fails to compute, then we can't use this local anyway
907+
// or the local is too large, then we don't want to.
908+
_ => {
909+
*val = ConstPropMode::NoPropagation;
910+
continue;
911+
}
906912
}
907913
}
908914
}

tests/crashes/123710.rs

-17
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Regression test for issue 123710.
2+
// Tests that the we do not ICE in KnownPanicsLint
3+
// when a union contains an enum with an repr(packed),
4+
// which is a repr not supported for enums
5+
6+
#[repr(packed)]
7+
//~^ ERROR attribute should be applied to a struct or union
8+
#[repr(u32)]
9+
enum E {
10+
A,
11+
B,
12+
C,
13+
}
14+
15+
fn main() {
16+
union InvalidTag {
17+
int: u32,
18+
e: E,
19+
//~^ ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
20+
}
21+
let _invalid_tag = InvalidTag { int: 4 };
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0517]: attribute should be applied to a struct or union
2+
--> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:6:8
3+
|
4+
LL | #[repr(packed)]
5+
| ^^^^^^
6+
...
7+
LL | / enum E {
8+
LL | | A,
9+
LL | | B,
10+
LL | | C,
11+
LL | | }
12+
| |_- not a struct or union
13+
14+
error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
15+
--> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:18:9
16+
|
17+
LL | e: E,
18+
| ^^^^
19+
|
20+
= note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
21+
help: wrap the field type in `ManuallyDrop<...>`
22+
|
23+
LL | e: std::mem::ManuallyDrop<E>,
24+
| +++++++++++++++++++++++ +
25+
26+
error: aborting due to 2 previous errors
27+
28+
Some errors have detailed explanations: E0517, E0740.
29+
For more information about an error, try `rustc --explain E0517`.

0 commit comments

Comments
 (0)