about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs20
-rw-r--r--tests/crashes/123710.rs17
-rw-r--r--tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs22
-rw-r--r--tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr29
4 files changed, 64 insertions, 24 deletions
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index b8dbf8a759f..b2030efca8f 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -896,13 +896,19 @@ impl CanConstProp {
         };
         for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
             let ty = body.local_decls[local].ty;
-            match tcx.layout_of(param_env.and(ty)) {
-                Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
-                // Either the layout fails to compute, then we can't use this local anyway
-                // or the local is too large, then we don't want to.
-                _ => {
-                    *val = ConstPropMode::NoPropagation;
-                    continue;
+            if ty.is_union() {
+                // Do not const prop unions as they can
+                // ICE during layout calc
+                *val = ConstPropMode::NoPropagation;
+            } else {
+                match tcx.layout_of(param_env.and(ty)) {
+                    Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
+                    // Either the layout fails to compute, then we can't use this local anyway
+                    // or the local is too large, then we don't want to.
+                    _ => {
+                        *val = ConstPropMode::NoPropagation;
+                        continue;
+                    }
                 }
             }
         }
diff --git a/tests/crashes/123710.rs b/tests/crashes/123710.rs
deleted file mode 100644
index f171fa7cebb..00000000000
--- a/tests/crashes/123710.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #123710
-
-#[repr(packed)]
-#[repr(u32)]
-enum E {
-    A,
-    B,
-    C,
-}
-
-fn main() {
-    union InvalidTag {
-        int: u32,
-        e: E,
-    }
-    let _invalid_tag = InvalidTag { int: 4 };
-}
diff --git a/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs
new file mode 100644
index 00000000000..2b93d0f8a60
--- /dev/null
+++ b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.rs
@@ -0,0 +1,22 @@
+// Regression test for issue 123710.
+// Tests that the we do not ICE in KnownPanicsLint
+// when a union contains an enum with an repr(packed),
+// which is a repr not supported for enums
+
+#[repr(packed)]
+//~^ ERROR attribute should be applied to a struct or union
+#[repr(u32)]
+enum E {
+    A,
+    B,
+    C,
+}
+
+fn main() {
+    union InvalidTag {
+        int: u32,
+        e: E,
+//~^ ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+    }
+    let _invalid_tag = InvalidTag { int: 4 };
+}
diff --git a/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr
new file mode 100644
index 00000000000..44dde6120e8
--- /dev/null
+++ b/tests/ui/lint/ice-const-prop-unions-known-panics-lint-123710.stderr
@@ -0,0 +1,29 @@
+error[E0517]: attribute should be applied to a struct or union
+  --> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:6:8
+   |
+LL |   #[repr(packed)]
+   |          ^^^^^^
+...
+LL | / enum E {
+LL | |     A,
+LL | |     B,
+LL | |     C,
+LL | | }
+   | |_- not a struct or union
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/ice-const-prop-unions-known-panics-lint-123710.rs:18:9
+   |
+LL |         e: E,
+   |         ^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |         e: std::mem::ManuallyDrop<E>,
+   |            +++++++++++++++++++++++ +
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0517, E0740.
+For more information about an error, try `rustc --explain E0517`.