From 004208fc46467c5e171e739559f77c0fafbbe87a Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 1 May 2020 15:52:08 +0200 Subject: [PATCH] Move recursion check for zsts back to read site instead of access check site. --- src/librustc_mir/interpret/memory.rs | 13 +------------ src/librustc_mir/interpret/operand.rs | 9 +++++++++ src/test/ui/consts/static-ice.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/consts/static-ice.rs 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 b924f20ce7c..05844eb126c 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -240,6 +240,15 @@ 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. The caller is likely + // to short-circuit on `None`, so we trigger the access here to + // make sure it happens. + 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/static-ice.rs b/src/test/ui/consts/static-ice.rs new file mode 100644 index 00000000000..a6d90e44e34 --- /dev/null +++ b/src/test/ui/consts/static-ice.rs @@ -0,0 +1,27 @@ +// check-pass + +#[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(); +}