about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-04 09:39:53 +0000
committerbors <bors@rust-lang.org>2020-05-04 09:39:53 +0000
commit6318d24ad8440fa30428b405be1174478e9536e3 (patch)
treeb72e4c8076fd4430b8ebef8bf0abf8118cb1367d
parentd6823ba1666fa5f65e5fdd17cfc78ff227c092f2 (diff)
parentc64c7766787e6d9d5b80b95832155a11cadcbe40 (diff)
downloadrust-6318d24ad8440fa30428b405be1174478e9536e3.tar.gz
rust-6318d24ad8440fa30428b405be1174478e9536e3.zip
Auto merge of #71751 - oli-obk:const_ice, r=RalfJung
Move recursion check for zsts back to read site instead of access check site

Reverts https://github.com/rust-lang/rust/pull/71140#discussion_r413709446

Fix #71612
Fix #71709

r? @RalfJung
-rw-r--r--src/librustc_mir/interpret/memory.rs13
-rw-r--r--src/librustc_mir/interpret/operand.rs7
-rw-r--r--src/test/ui/consts/ice-zst-static-access.rs32
3 files changed, 40 insertions, 12 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index d1881524172..39e428cee1d 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -400,18 +400,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
 
                 // We can still be zero-sized in this branch, in which case we have to
                 // return `None`.
-                if size.bytes() == 0 {
-                    // We may be reading from a static.
-                    // In order to ensure that `static FOO: Type = FOO;` causes a cycle error
-                    // instead of magically pulling *any* ZST value from the ether, we need to
-                    // actually access the referenced allocation. The caller is likely
-                    // to short-circuit on `None`, so we trigger the access here to
-                    // make sure it happens.
-                    self.get_raw(ptr.alloc_id)?;
-                    None
-                } else {
-                    Some(ptr)
-                }
+                if size.bytes() == 0 { None } else { Some(ptr) }
             }
         })
     }
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index e2fb9de486f..cc9fc170f6e 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -240,6 +240,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         {
             Some(ptr) => ptr,
             None => {
+                if let Scalar::Ptr(ptr) = mplace.ptr {
+                    // We may be reading from a static.
+                    // In order to ensure that `static FOO: Type = FOO;` causes a cycle error
+                    // instead of magically pulling *any* ZST value from the ether, we need to
+                    // actually access the referenced allocation.
+                    self.memory.get_raw(ptr.alloc_id)?;
+                }
                 return Ok(Some(ImmTy {
                     // zero-sized type
                     imm: Scalar::zst().into(),
diff --git a/src/test/ui/consts/ice-zst-static-access.rs b/src/test/ui/consts/ice-zst-static-access.rs
new file mode 100644
index 00000000000..b68e442a57c
--- /dev/null
+++ b/src/test/ui/consts/ice-zst-static-access.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+// This is a regression test for ICEs from
+// https://github.com/rust-lang/rust/issues/71612
+// and
+// https://github.com/rust-lang/rust/issues/71709
+
+#[derive(Copy, Clone)]
+pub struct Glfw;
+
+static mut GLFW: Option<Glfw> = None;
+pub fn new() -> Glfw {
+    unsafe {
+        if let Some(glfw) = GLFW {
+            return glfw;
+        } else {
+            todo!()
+        }
+    };
+}
+
+extern "C" {
+    static _dispatch_queue_attr_concurrent: [u8; 0];
+}
+
+static DISPATCH_QUEUE_CONCURRENT: &'static [u8; 0] =
+    unsafe { &_dispatch_queue_attr_concurrent };
+
+fn main() {
+    *DISPATCH_QUEUE_CONCURRENT;
+    new();
+}