about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2025-08-23 18:22:38 +0200
committerSamuel Tardieu <sam@rfc1149.net>2025-08-23 19:25:58 +0200
commit323e23005a6a2025508e6064a0f88dae09cfa127 (patch)
tree29a08086269672d21f1436c1a4d7357da229de00 /compiler/rustc_mir_transform/src
parent6d6a08cf590ec26296447b8d2cf2329bb64c303a (diff)
downloadrust-323e23005a6a2025508e6064a0f88dae09cfa127.tar.gz
rust-323e23005a6a2025508e6064a0f88dae09cfa127.zip
Fix ICE when validating transmuting ZST to inhabited enum
MIR validation attempts to determine the number of bytes needed to
represent the size of the source type to compute the discriminant for
the inhabited target enum. For a ZST source, there is no source data to
use as a discriminant so no proper runtime check can be generated.

Since that should never be possible, insert a delayed bug to ensure the
problem has been properly reported to the user by the type checker.
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/check_enums.rs15
1 files changed, 15 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,