about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-12-09 11:31:32 +0000
committerbors <bors@rust-lang.org>2020-12-09 11:31:32 +0000
commitcc03ee6702053ded253c3656cbd02f0bfdf25c73 (patch)
treeacc84a4954fc25ccad877b6d35b7a2b6734c85aa
parentc0bfe3485f97f267cc8adec724f109c56dab5526 (diff)
parent84fe7cf24eb801348c120218cafe80efda597f04 (diff)
downloadrust-cc03ee6702053ded253c3656cbd02f0bfdf25c73.tar.gz
rust-cc03ee6702053ded253c3656cbd02f0bfdf25c73.zip
Auto merge of #78679 - oli-obk:temp_lifetime, r=eddyb
Also generate `StorageDead` in constants

r? `@eddyb`

None of this special casing is actually necessary since we started promoting within constants and statics.

We may want to keep some of it around out of perf reasons, but it's not required for user visible behaviour

somewhat related: #68622
-rw-r--r--compiler/rustc_mir/src/interpret/eval_context.rs22
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs7
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs40
-rw-r--r--src/test/mir-opt/const-promotion-extern-static.rs3
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff3
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir17
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff3
-rw-r--r--src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir44
10 files changed, 92 insertions, 57 deletions
diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs
index 05b4d1c410d..d48b7fb3b92 100644
--- a/compiler/rustc_mir/src/interpret/eval_context.rs
+++ b/compiler/rustc_mir/src/interpret/eval_context.rs
@@ -4,7 +4,7 @@ use std::mem;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_hir::{self as hir, def::DefKind, def_id::DefId, definitions::DefPathData};
+use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
 use rustc_index::vec::IndexVec;
 use rustc_macros::HashStable;
 use rustc_middle::ich::StableHashingContext;
@@ -700,21 +700,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let mut locals = IndexVec::from_elem(dummy, &body.local_decls);
 
         // Now mark those locals as dead that we do not want to initialize
-        match self.tcx.def_kind(instance.def_id()) {
-            // statics and constants don't have `Storage*` statements, no need to look for them
-            //
-            // FIXME: The above is likely untrue. See
-            // <https://github.com/rust-lang/rust/pull/70004#issuecomment-602022110>. Is it
-            // okay to ignore `StorageDead`/`StorageLive` annotations during CTFE?
-            DefKind::Static | DefKind::Const | DefKind::AssocConst => {}
-            _ => {
-                // Mark locals that use `Storage*` annotations as dead on function entry.
-                let always_live = AlwaysLiveLocals::new(self.body());
-                for local in locals.indices() {
-                    if !always_live.contains(local) {
-                        locals[local].value = LocalValue::Dead;
-                    }
-                }
+        // Mark locals that use `Storage*` annotations as dead on function entry.
+        let always_live = AlwaysLiveLocals::new(self.body());
+        for local in locals.indices() {
+            if !always_live.contains(local) {
+                locals[local].value = LocalValue::Dead;
             }
         }
         // done
diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index cf075abc94b..60f8d8c8a9f 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -19,7 +19,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         M: Mirror<'tcx, Output = Expr<'tcx>>,
     {
         let local_scope = self.local_scope();
-        self.as_operand(block, local_scope, expr)
+        self.as_operand(block, Some(local_scope), expr)
     }
 
     /// Returns an operand suitable for use until the end of the current scope expression and
@@ -79,7 +79,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         M: Mirror<'tcx, Output = Expr<'tcx>>,
     {
         let local_scope = self.local_scope();
-        self.as_call_operand(block, local_scope, expr)
+        self.as_call_operand(block, Some(local_scope), expr)
     }
 
     /// Compile `expr` into a value that can be used as an operand.
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index c0e4141a558..6537ba745c1 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -25,7 +25,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         M: Mirror<'tcx, Output = Expr<'tcx>>,
     {
         let local_scope = self.local_scope();
-        self.as_rvalue(block, local_scope, expr)
+        self.as_rvalue(block, Some(local_scope), expr)
     }
 
     /// Compile `expr`, yielding an rvalue.
@@ -445,9 +445,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place),
         );
 
-        // In constants, temp_lifetime is None. We should not need to drop
-        // anything because no values with a destructor can be created in
-        // a constant at this time, even if the type may need dropping.
+        // See the comment in `expr_as_temp` and on the `rvalue_scopes` field for why
+        // this can be `None`.
         if let Some(temp_lifetime) = temp_lifetime {
             this.schedule_drop_storage_and_value(upvar_span, temp_lifetime, temp);
         }
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 5f9743b7f59..1f70fdb5ae3 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -79,7 +79,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                 // (#66975) Source could be a const of type `!`, so has to
                 // exist in the generated MIR.
-                unpack!(block = this.as_temp(block, this.local_scope(), source, Mutability::Mut,));
+                unpack!(block = this.as_temp(block, Some(this.local_scope()), source, Mutability::Mut,));
 
                 // This is an optimization. If the expression was a call then we already have an
                 // unreachable block. Don't bother to terminate it and create a new one.
@@ -300,7 +300,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // (evaluating them in order given by user)
                 let fields_map: FxHashMap<_, _> = fields
                     .into_iter()
-                    .map(|f| (f.name, unpack!(block = this.as_operand(block, scope, f.expr))))
+                    .map(|f| (f.name, unpack!(block = this.as_operand(block, Some(scope), f.expr))))
                     .collect();
 
                 let field_names = this.hir.all_fields(adt_def, variant_index);
@@ -468,7 +468,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
             ExprKind::Yield { value } => {
                 let scope = this.local_scope();
-                let value = unpack!(block = this.as_operand(block, scope, value));
+                let value = unpack!(block = this.as_operand(block, Some(scope), value));
                 let resume = this.cfg.start_new_block();
                 this.record_operands_moved(slice::from_ref(&value));
                 this.cfg.terminate(
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 468b3484ca5..e137f77ffbb 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -85,7 +85,6 @@ use crate::build::matches::{ArmHasGuard, Candidate};
 use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG};
 use crate::thir::{Arm, Expr, ExprRef, LintLevel};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir as hir;
 use rustc_index::vec::IndexVec;
 use rustc_middle::middle::region;
 use rustc_middle::mir::*;
@@ -740,18 +739,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// We would allocate the box but then free it on the unwinding
     /// path; we would also emit a free on the 'success' path from
     /// panic, but that will turn out to be removed as dead-code.
-    ///
-    /// When building statics/constants, returns `None` since
-    /// intermediate values do not have to be dropped in that case.
-    crate fn local_scope(&self) -> Option<region::Scope> {
-        match self.hir.body_owner_kind {
-            hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) =>
-            // No need to free storage in this context.
-            {
-                None
-            }
-            hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => Some(self.scopes.topmost()),
-        }
+    crate fn local_scope(&self) -> region::Scope {
+        self.scopes.topmost()
     }
 
     // Scheduling drops
@@ -938,23 +927,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// not the `DROP(_X)` itself, but the (spurious) unwind pathways
     /// that it creates. See #64391 for an example.
     crate fn record_operands_moved(&mut self, operands: &[Operand<'tcx>]) {
-        let scope = match self.local_scope() {
-            None => {
-                // if there is no local scope, operands won't be dropped anyway
-                return;
-            }
+        let local_scope = self.local_scope();
+        let scope = self.scopes.scopes.last_mut().unwrap();
 
-            Some(local_scope) => {
-                let top_scope = self.scopes.scopes.last_mut().unwrap();
-                assert!(
-                    top_scope.region_scope == local_scope,
-                    "local scope ({:?}) is not the topmost scope!",
-                    local_scope
-                );
-
-                top_scope
-            }
-        };
+        assert_eq!(
+            scope.region_scope, local_scope,
+            "local scope is not the topmost scope!",
+        );
 
         // look for moves of a local variable, like `MOVE(_X)`
         let locals_moved = operands
@@ -993,9 +972,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         match cond {
             // Don't try to drop a constant
             Operand::Constant(_) => (),
-            // If constants and statics, we don't generate StorageLive for this
-            // temporary, so don't try to generate StorageDead for it either.
-            _ if self.local_scope().is_none() => (),
             Operand::Copy(place) | Operand::Move(place) => {
                 if let Some(cond_temp) = place.as_local() {
                     // Manually drop the condition on both branches.
diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs
index 9c30e040031..0f13fe1b48c 100644
--- a/src/test/mir-opt/const-promotion-extern-static.rs
+++ b/src/test/mir-opt/const-promotion-extern-static.rs
@@ -12,4 +12,7 @@ static mut BAR: *const &i32 = [&Y].as_ptr();
 // EMIT_MIR const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir
 static mut FOO: *const &i32 = [unsafe { &X }].as_ptr();
 
+// EMIT_MIR const_promotion_extern_static.BOP.mir_map.0.mir
+static BOP: &i32 = &13;
+
 fn main() {}
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
index bbce9c288ef..5ba76c4f0bd 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -33,6 +33,8 @@
 +                                          // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR), const_param_did: None }, [], Some(promoted[0])) }
 +         _2 = &(*_6);                     // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
           _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35
+-         StorageDead(_4);                 // scope 0 at $DIR/const-promotion-extern-static.rs:9:34: 9:35
+          StorageDead(_2);                 // scope 0 at $DIR/const-promotion-extern-static.rs:9:34: 9:35
           _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
                                            // mir::Constant
                                            // + span: $DIR/const-promotion-extern-static.rs:9:36: 9:42
@@ -42,6 +44,7 @@
       bb1: {
 -         StorageDead(_5);                 // scope 0 at $DIR/const-promotion-extern-static.rs:9:43: 9:44
 -         StorageDead(_3);                 // scope 0 at $DIR/const-promotion-extern-static.rs:9:43: 9:44
+          StorageDead(_1);                 // scope 0 at $DIR/const-promotion-extern-static.rs:9:43: 9:44
           return;                          // scope 0 at $DIR/const-promotion-extern-static.rs:9:1: 9:45
       }
   
diff --git a/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
new file mode 100644
index 00000000000..4d24387afc7
--- /dev/null
+++ b/src/test/mir-opt/const_promotion_extern_static.BOP.mir_map.0.mir
@@ -0,0 +1,17 @@
+// MIR for `BOP` 0 mir_map
+
+static BOP: &i32 = {
+    let mut _0: &i32;                    // return place in scope 0 at $DIR/const-promotion-extern-static.rs:16:13: 16:17
+    let _1: &i32;                        // in scope 0 at $DIR/const-promotion-extern-static.rs:16:20: 16:23
+    let _2: i32;                         // in scope 0 at $DIR/const-promotion-extern-static.rs:16:21: 16:23
+
+    bb0: {
+        StorageLive(_1);                 // scope 0 at $DIR/const-promotion-extern-static.rs:16:20: 16:23
+        StorageLive(_2);                 // scope 0 at $DIR/const-promotion-extern-static.rs:16:21: 16:23
+        _2 = const 13_i32;               // scope 0 at $DIR/const-promotion-extern-static.rs:16:21: 16:23
+        _1 = &_2;                        // scope 0 at $DIR/const-promotion-extern-static.rs:16:20: 16:23
+        _0 = &(*_1);                     // scope 0 at $DIR/const-promotion-extern-static.rs:16:20: 16:23
+        StorageDead(_1);                 // scope 0 at $DIR/const-promotion-extern-static.rs:16:22: 16:23
+        return;                          // scope 0 at $DIR/const-promotion-extern-static.rs:16:1: 16:24
+    }
+}
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index 82277b2a21c..1565cc7d5e7 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -35,6 +35,8 @@
 +                                          // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0])) }
 +         _2 = &(*_6);                     // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
           _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
+-         StorageDead(_4);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:45: 13:46
+          StorageDead(_2);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:45: 13:46
           _0 = core::slice::<impl [&i32]>::as_ptr(move _1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
                                            // mir::Constant
                                            // + span: $DIR/const-promotion-extern-static.rs:13:47: 13:53
@@ -44,6 +46,7 @@
       bb1: {
 -         StorageDead(_5);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:54: 13:55
 -         StorageDead(_3);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:54: 13:55
+          StorageDead(_1);                 // scope 0 at $DIR/const-promotion-extern-static.rs:13:54: 13:55
           return;                          // scope 0 at $DIR/const-promotion-extern-static.rs:13:1: 13:56
       }
   
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
index 6d05e8278ba..6c22af787d3 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
+++ b/src/test/mir-opt/storage_live_dead_in_statics.XXX.mir_map.0.mir
@@ -143,9 +143,52 @@ static XXX: &Foo = {
         StorageLive(_48);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:25: 21:31
         _48 = (const 0_u32, const 3_u32); // scope 0 at $DIR/storage_live_dead_in_statics.rs:21:25: 21:31
         _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48]; // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:12: 22:6
+        StorageDead(_48);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_47);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_46);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_45);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_44);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_43);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_42);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_41);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_40);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_39);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_38);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_37);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_36);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_35);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_34);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_33);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_32);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_31);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_30);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_29);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_28);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_27);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_26);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_25);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_24);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_23);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_22);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_21);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_20);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_19);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_18);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_17);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_16);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_15);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_14);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_13);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_12);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_11);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_10);                // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_9);                 // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_8);                 // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
+        StorageDead(_7);                 // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
         _5 = &_6;                        // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:11: 22:6
         _4 = &(*_5);                     // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:11: 22:6
         _3 = move _4 as &[(u32, u32)] (Pointer(Unsize)); // scope 0 at $DIR/storage_live_dead_in_statics.rs:7:11: 22:6
+        StorageDead(_4);                 // scope 0 at $DIR/storage_live_dead_in_statics.rs:22:5: 22:6
         _2 = Foo { tup: const "hi", data: move _3 }; // scope 0 at $DIR/storage_live_dead_in_statics.rs:5:29: 23:2
                                          // ty::Const
                                          // + ty: &str
@@ -153,6 +196,7 @@ static XXX: &Foo = {
                                          // mir::Constant
                                          // + span: $DIR/storage_live_dead_in_statics.rs:6:10: 6:14
                                          // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [104, 105], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [3], len: Size { raw: 2 } }, size: Size { raw: 2 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 2 }) }
+        StorageDead(_3);                 // scope 0 at $DIR/storage_live_dead_in_statics.rs:23:1: 23:2
         _1 = &_2;                        // scope 0 at $DIR/storage_live_dead_in_statics.rs:5:28: 23:2
         _0 = &(*_1);                     // scope 0 at $DIR/storage_live_dead_in_statics.rs:5:28: 23:2
         StorageDead(_5);                 // scope 0 at $DIR/storage_live_dead_in_statics.rs:23:1: 23:2