@@ -24,6 +24,7 @@ use super::{
24
24
Immediate , MPlaceTy , Machine , MemPlace , MemPlaceMeta , Memory , OpTy , Operand , Place , PlaceTy ,
25
25
ScalarMaybeUndef , StackPopJump ,
26
26
} ;
27
+ use crate :: util:: storage:: AlwaysLiveLocals ;
27
28
28
29
pub struct InterpCx < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > {
29
30
/// Stores the `Machine` instance.
@@ -610,17 +611,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
610
611
// Now mark those locals as dead that we do not want to initialize
611
612
match self . tcx . def_kind ( instance. def_id ( ) ) {
612
613
// 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?
613
618
Some ( DefKind :: Static ) | Some ( DefKind :: Const ) | Some ( DefKind :: AssocConst ) => { }
614
619
_ => {
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 ;
624
625
}
625
626
}
626
627
}
0 commit comments