about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/check_enums.rs15
-rw-r--r--tests/ui/mir/validate/ice-zst-as-discr-145786.rs14
-rw-r--r--tests/ui/mir/validate/ice-zst-as-discr-145786.stderr12
3 files changed, 41 insertions, 0 deletions
diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs
index 33a87cb9873..12447dc7cbb 100644
--- a/compiler/rustc_mir_transform/src/check_enums.rs
+++ b/compiler/rustc_mir_transform/src/check_enums.rs
@@ -48,6 +48,21 @@ impl<'tcx> crate::MirPass<'tcx> for CheckEnums {
                     let new_block = split_block(basic_blocks, location);
 
                     match check {
+                        EnumCheckType::Direct { op_size, .. }
+                        | EnumCheckType::WithNiche { op_size, .. }
+                            if op_size.bytes() == 0 =>
+                        {
+                            // It is never valid to use a ZST as a discriminant for an inhabited enum, but that will
+                            // have been caught by the type checker. Do nothing but ensure that a bug has been signaled.
+                            tcx.dcx().span_delayed_bug(
+                                source_info.span,
+                                "cannot build enum discriminant from zero-sized type",
+                            );
+                            basic_blocks[block].terminator = Some(Terminator {
+                                source_info,
+                                kind: TerminatorKind::Goto { target: new_block },
+                            });
+                        }
                         EnumCheckType::Direct { source_op, discr, op_size, valid_discrs } => {
                             insert_direct_enum_check(
                                 tcx,
diff --git a/tests/ui/mir/validate/ice-zst-as-discr-145786.rs b/tests/ui/mir/validate/ice-zst-as-discr-145786.rs
new file mode 100644
index 00000000000..616736bcf12
--- /dev/null
+++ b/tests/ui/mir/validate/ice-zst-as-discr-145786.rs
@@ -0,0 +1,14 @@
+// Do not attempt to take the discriminant as the source
+// converted to a `u128`, that won't work for ZST.
+//
+//@ compile-flags: -Zvalidate-mir
+
+enum A {
+    B,
+    C,
+}
+
+fn main() {
+    let _: A = unsafe { std::mem::transmute(()) };
+    //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
diff --git a/tests/ui/mir/validate/ice-zst-as-discr-145786.stderr b/tests/ui/mir/validate/ice-zst-as-discr-145786.stderr
new file mode 100644
index 00000000000..b0bca1eb39c
--- /dev/null
+++ b/tests/ui/mir/validate/ice-zst-as-discr-145786.stderr
@@ -0,0 +1,12 @@
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+  --> $DIR/ice-zst-as-discr-145786.rs:12:25
+   |
+LL |     let _: A = unsafe { std::mem::transmute(()) };
+   |                         ^^^^^^^^^^^^^^^^^^^
+   |
+   = note: source type: `()` (0 bits)
+   = note: target type: `A` (8 bits)
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0512`.