about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorOliver Schneider <github35764891676564198441@oli-obk.de>2018-09-10 17:46:30 +0200
committerOliver Schneider <github35764891676564198441@oli-obk.de>2018-09-11 11:27:12 +0200
commitd1b5231aa75d6c25efc839454331d3c9fb09ffb3 (patch)
tree8bfa3313997d78526da9d9575f3c6bc555b68972 /src
parent24dca6aecaded209d47aba6e60e0b87eae2d49d6 (diff)
downloadrust-d1b5231aa75d6c25efc839454331d3c9fb09ffb3.tar.gz
rust-d1b5231aa75d6c25efc839454331d3c9fb09ffb3.zip
Fix const eval of ZST index operations to make the static assertion work
Diffstat (limited to 'src')
-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() {}