@@ -24,6 +24,7 @@ use super::{
2424 Immediate , MPlaceTy , Machine , MemPlace , MemPlaceMeta , Memory , OpTy , Operand , Place , PlaceTy ,
2525 ScalarMaybeUndef , StackPopJump ,
2626} ;
27+ use crate :: util:: storage:: AlwaysLiveLocals ;
2728
2829pub struct InterpCx < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > {
2930 /// Stores the `Machine` instance.
@@ -610,17 +611,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
610611 // Now mark those locals as dead that we do not want to initialize
611612 match self . tcx . def_kind ( instance. def_id ( ) ) {
612613 // statics and constants don't have `Storage*` statements, no need to look for them
614+ //
615+ // FIXME: The above is likely untrue. See
616+ // <https://github.com/rust-lang/rust/pull/70004#issuecomment-602022110>. Is it
617+ // okay to ignore `StorageDead`/`StorageLive` annotations during CTFE?
613618 Some ( DefKind :: Static ) | Some ( DefKind :: Const ) | Some ( DefKind :: AssocConst ) => { }
614619 _ => {
615- for block in body. basic_blocks ( ) {
616- for stmt in block. statements . iter ( ) {
617- use rustc_middle:: mir:: StatementKind :: { StorageDead , StorageLive } ;
618- match stmt. kind {
619- StorageLive ( local) | StorageDead ( local) => {
620- locals[ local] . value = LocalValue :: Dead ;
621- }
622- _ => { }
623- }
620+ // Mark locals that use `Storage*` annotations as dead on function entry.
621+ let always_live = AlwaysLiveLocals :: new ( self . body ( ) ) ;
622+ for local in locals. indices ( ) {
623+ if !always_live. contains ( local) {
624+ locals[ local] . value = LocalValue :: Dead ;
624625 }
625626 }
626627 }
0 commit comments