From b75dfa8a2bac745d7d09212e3e28cb4f0bc28fdf Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 25 Jul 2019 19:29:48 +0200 Subject: [PATCH] Don't access a static just for its size and alignment --- src/librustc_mir/interpret/memory.rs | 27 ++++++++++++------------ src/test/ui/consts/static-cycle-error.rs | 11 ++++++++++ 2 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/consts/static-cycle-error.rs diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3f2a76a77be..674ae290706 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -535,6 +535,19 @@ pub fn get_size_and_align( id: AllocId, liveness: AllocCheck, ) -> InterpResult<'static, (Size, Align)> { + // Allocations of `static` items + // Can't do this in the match argument, we may get cycle errors since the lock would + // be held throughout the match. + let alloc = self.tcx.alloc_map.lock().get(id); + match alloc { + Some(GlobalAlloc::Static(did)) => { + // Use size and align of the type + let ty = self.tcx.type_of(did); + let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); + return Ok((layout.size, layout.align.abi)); + } + _ => {} + } // Regular allocations. if let Ok(alloc) = self.get(id) { return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)); @@ -548,20 +561,6 @@ pub fn get_size_and_align( Ok((Size::ZERO, Align::from_bytes(1).unwrap())) }; } - // Foreign statics. - // Can't do this in the match argument, we may get cycle errors since the lock would - // be held throughout the match. - let alloc = self.tcx.alloc_map.lock().get(id); - match alloc { - Some(GlobalAlloc::Static(did)) => { - assert!(self.tcx.is_foreign_item(did)); - // Use size and align of the type - let ty = self.tcx.type_of(did); - let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); - return Ok((layout.size, layout.align.abi)); - } - _ => {} - } // The rest must be dead. if let AllocCheck::MaybeDead = liveness { // Deallocated pointers are allowed, we should be able to find diff --git a/src/test/ui/consts/static-cycle-error.rs b/src/test/ui/consts/static-cycle-error.rs new file mode 100644 index 00000000000..9ce050aae21 --- /dev/null +++ b/src/test/ui/consts/static-cycle-error.rs @@ -0,0 +1,11 @@ +// check-pass + +struct Foo { + foo: Option<&'static Foo> +} + +static FOO: Foo = Foo { + foo: Some(&FOO), +}; + +fn main() {} -- 2.44.0