diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index d1881524172cc..39e428cee1d7b 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 e2fb9de486f09..cc9fc170f6e79 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 0000000000000..b68e442a57c71 --- /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 = 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(); +}