about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/interpret/operand.rs14
-rw-r--r--src/test/ui/consts/const-eval/zst_operand_eval.rs5
2 files changed, 15 insertions, 4 deletions
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 461285ff9bc..8bb93d09a2a 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -340,7 +340,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
 
         let field = field.try_into().unwrap();
         let field_layout = op.layout.field(self, field)?;
-        if field_layout.size.bytes() == 0 {
+        if field_layout.is_zst() {
             let val = Value::Scalar(Scalar::zst().into());
             return Ok(OpTy { op: Operand::Immediate(val), layout: field_layout });
         }
@@ -397,9 +397,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
             Field(field, _) => self.operand_field(base, field.index() as u64)?,
             Downcast(_, variant) => self.operand_downcast(base, variant)?,
             Deref => self.deref_operand(base)?.into(),
-            // The rest should only occur as mplace, we do not use Immediates for types
-            // allowing such operations.  This matches place_projection forcing an allocation.
-            Subslice { .. } | ConstantIndex { .. } | Index(_) => {
+            Subslice { .. } | ConstantIndex { .. } | Index(_) => if base.layout.is_zst() {
+                OpTy {
+                    op: Operand::Immediate(Value::Scalar(Scalar::zst().into())),
+                    // the actual index doesn't matter, so we just pick a convenient one like 0
+                    layout: base.layout.field(self, 0)?,
+                }
+            } else {
+                // The rest should only occur as mplace, we do not use Immediates for types
+                // allowing such operations.  This matches place_projection forcing an allocation.
                 let mplace = base.to_mem_place();
                 self.mplace_projection(mplace, proj_elem)?.into()
             }
diff --git a/src/test/ui/consts/const-eval/zst_operand_eval.rs b/src/test/ui/consts/const-eval/zst_operand_eval.rs
new file mode 100644
index 00000000000..c6deb88d4f1
--- /dev/null
+++ b/src/test/ui/consts/const-eval/zst_operand_eval.rs
@@ -0,0 +1,5 @@
+// compile-pass
+
+static ASSERT: () = [()][(std::mem::size_of::<u32>() != 4) as usize];
+
+fn main() {}