about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2020-03-29 14:17:27 -0700
committerDylan MacKenzie <ecstaticmorse@gmail.com>2020-04-09 12:48:31 -0700
commit335fd6b456ac75f5a5bd34d71855dc892bdd8e2f (patch)
tree795c3c404b028903d685caa10cb593e2d928e713
parentfcd1f5bc0a1090f295667dc0fdb7f238672b0302 (diff)
downloadrust-335fd6b456ac75f5a5bd34d71855dc892bdd8e2f.tar.gz
rust-335fd6b456ac75f5a5bd34d71855dc892bdd8e2f.zip
Use new utility in `eval_context`
-rw-r--r--src/librustc_mir/interpret/eval_context.rs19
1 files changed, 10 insertions, 9 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 72d20644fe8..e0b5f634bf3 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -24,6 +24,7 @@ use super::{
     Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
     ScalarMaybeUndef, StackPopJump,
 };
+use crate::util::storage::AlwaysLiveLocals;
 
 pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
     /// Stores the `Machine` instance.
@@ -610,17 +611,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // 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?
                 Some(DefKind::Static) | Some(DefKind::Const) | Some(DefKind::AssocConst) => {}
                 _ => {
-                    for block in body.basic_blocks() {
-                        for stmt in block.statements.iter() {
-                            use rustc_middle::mir::StatementKind::{StorageDead, StorageLive};
-                            match stmt.kind {
-                                StorageLive(local) | StorageDead(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;
                         }
                     }
                 }