@@ -461,6 +461,7 @@ impl Inliner<'tcx> {
461461 tcx : self . tcx ,
462462 callsite_span : callsite. source_info . span ,
463463 body_span : callee_body. span ,
464+ always_live_locals : BitSet :: new_filled ( callee_body. local_decls . len ( ) ) ,
464465 } ;
465466
466467 // Map all `Local`s, `SourceScope`s and `BasicBlock`s to new ones
@@ -492,6 +493,34 @@ impl Inliner<'tcx> {
492493 }
493494 }
494495
496+ // If there are any locals without storage markers, give them storage only for the
497+ // duration of the call.
498+ for local in callee_body. vars_and_temps_iter ( ) {
499+ if integrator. always_live_locals . contains ( local) {
500+ let new_local = integrator. map_local ( local) ;
501+ caller_body[ callsite. block ] . statements . push ( Statement {
502+ source_info : callsite. source_info ,
503+ kind : StatementKind :: StorageLive ( new_local) ,
504+ } ) ;
505+ }
506+ }
507+ if let Some ( block) = callsite. target {
508+ // To avoid repeated O(n) insert, push any new statements to the end and rotate
509+ // the slice once.
510+ let mut n = 0 ;
511+ for local in callee_body. vars_and_temps_iter ( ) . rev ( ) {
512+ if integrator. always_live_locals . contains ( local) {
513+ let new_local = integrator. map_local ( local) ;
514+ caller_body[ block] . statements . push ( Statement {
515+ source_info : callsite. source_info ,
516+ kind : StatementKind :: StorageDead ( new_local) ,
517+ } ) ;
518+ n += 1 ;
519+ }
520+ }
521+ caller_body[ block] . statements . rotate_right ( n) ;
522+ }
523+
495524 // Insert all of the (mapped) parts of the callee body into the caller.
496525 caller_body. local_decls . extend (
497526 // FIXME(eddyb) make `Range<Local>` iterable so that we can use
@@ -673,6 +702,7 @@ struct Integrator<'a, 'tcx> {
673702 tcx : TyCtxt < ' tcx > ,
674703 callsite_span : Span ,
675704 body_span : Span ,
705+ always_live_locals : BitSet < Local > ,
676706}
677707
678708impl < ' a , ' tcx > Integrator < ' a , ' tcx > {
@@ -762,6 +792,15 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
762792 }
763793 }
764794
795+ fn visit_statement ( & mut self , statement : & mut Statement < ' tcx > , location : Location ) {
796+ if let StatementKind :: StorageLive ( local) | StatementKind :: StorageDead ( local) =
797+ statement. kind
798+ {
799+ self . always_live_locals . remove ( local) ;
800+ }
801+ self . super_statement ( statement, location) ;
802+ }
803+
765804 fn visit_terminator ( & mut self , terminator : & mut Terminator < ' tcx > , loc : Location ) {
766805 // Don't try to modify the implicit `_0` access on return (`return` terminators are
767806 // replaced down below anyways).
0 commit comments