@@ -459,6 +459,7 @@ impl Inliner<'tcx> {
459459 tcx : self . tcx ,
460460 callsite_span : callsite. source_info . span ,
461461 body_span : callee_body. span ,
462+ always_live_locals : BitSet :: new_filled ( callee_body. local_decls . len ( ) ) ,
462463 } ;
463464
464465 // Map all `Local`s, `SourceScope`s and `BasicBlock`s to new ones
@@ -490,6 +491,34 @@ impl Inliner<'tcx> {
490491 }
491492 }
492493
494+ // If there are any locals without storage markers, give them storage only for the
495+ // duration of the call.
496+ for local in callee_body. vars_and_temps_iter ( ) {
497+ if integrator. always_live_locals . contains ( local) {
498+ let new_local = integrator. map_local ( local) ;
499+ caller_body[ callsite. block ] . statements . push ( Statement {
500+ source_info : callsite. source_info ,
501+ kind : StatementKind :: StorageLive ( new_local) ,
502+ } ) ;
503+ }
504+ }
505+ if let Some ( block) = callsite. target {
506+ // To avoid repeated O(n) insert, push any new statements to the end and rotate
507+ // the slice once.
508+ let mut n = 0 ;
509+ for local in callee_body. vars_and_temps_iter ( ) . rev ( ) {
510+ if integrator. always_live_locals . contains ( local) {
511+ let new_local = integrator. map_local ( local) ;
512+ caller_body[ block] . statements . push ( Statement {
513+ source_info : callsite. source_info ,
514+ kind : StatementKind :: StorageDead ( new_local) ,
515+ } ) ;
516+ n += 1 ;
517+ }
518+ }
519+ caller_body[ block] . statements . rotate_right ( n) ;
520+ }
521+
493522 // Insert all of the (mapped) parts of the callee body into the caller.
494523 caller_body. local_decls . extend (
495524 // FIXME(eddyb) make `Range<Local>` iterable so that we can use
@@ -670,6 +699,7 @@ struct Integrator<'a, 'tcx> {
670699 tcx : TyCtxt < ' tcx > ,
671700 callsite_span : Span ,
672701 body_span : Span ,
702+ always_live_locals : BitSet < Local > ,
673703}
674704
675705impl < ' a , ' tcx > Integrator < ' a , ' tcx > {
@@ -759,6 +789,15 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
759789 }
760790 }
761791
792+ fn visit_statement ( & mut self , statement : & mut Statement < ' tcx > , location : Location ) {
793+ if let StatementKind :: StorageLive ( local) | StatementKind :: StorageDead ( local) =
794+ statement. kind
795+ {
796+ self . always_live_locals . remove ( local) ;
797+ }
798+ self . super_statement ( statement, location) ;
799+ }
800+
762801 fn visit_terminator ( & mut self , terminator : & mut Terminator < ' tcx > , loc : Location ) {
763802 // Don't try to modify the implicit `_0` access on return (`return` terminators are
764803 // replaced down below anyways).
0 commit comments