about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-07-25 19:29:48 +0200
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-07-25 19:29:48 +0200
commitb75dfa8a2bac745d7d09212e3e28cb4f0bc28fdf (patch)
tree23b4a57b801ebd793ef3eb09c191833eedbe0905
parenteedf6ce4ef54bb03818ab21d714f1b9f13a6b31c (diff)
downloadrust-b75dfa8a2bac745d7d09212e3e28cb4f0bc28fdf.tar.gz
rust-b75dfa8a2bac745d7d09212e3e28cb4f0bc28fdf.zip
Don't access a static just for its size and alignment
-rw-r--r--src/librustc_mir/interpret/memory.rs27
-rw-r--r--src/test/ui/consts/static-cycle-error.rs11
2 files changed, 24 insertions, 14 deletions
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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         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 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                 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() {}