@@ -62,6 +62,18 @@ pub(crate) enum DeclareLetBindings {
6262     LetNotPermitted , 
6363} 
6464
65+ /// Used by [`Builder::bind_matched_candidate_for_arm_body`] to determine 
66+ /// whether or not to call [`Builder::storage_live_binding`] to emit 
67+ /// [`StatementKind::StorageLive`]. 
68+ #[ derive( Clone ,  Copy ) ]  
69+ pub ( crate )  enum  EmitStorageLive  { 
70+     /// Yes, emit `StorageLive` as normal. 
71+      Yes , 
72+     /// No, don't emit `StorageLive`. The caller has taken responsibility for 
73+      /// emitting `StorageLive` as appropriate. 
74+      No , 
75+ } 
76+ 
6577impl < ' a ,  ' tcx >  Builder < ' a ,  ' tcx >  { 
6678    /// Lowers a condition in a way that ensures that variables bound in any let 
6779     /// expressions are definitely initialized in the if body. 
@@ -174,7 +186,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
174186                Some ( args. variable_source_info . scope ) , 
175187                args. variable_source_info . span , 
176188                args. declare_let_bindings , 
177-                 false , 
189+                 EmitStorageLive :: Yes , 
178190            ) , 
179191            _ => { 
180192                let  mut  block = block; 
@@ -467,7 +479,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
467479                        & fake_borrow_temps, 
468480                        scrutinee_span, 
469481                        Some ( ( arm,  match_scope) ) , 
470-                         false , 
482+                         EmitStorageLive :: Yes , 
471483                    ) ; 
472484
473485                    this. fixed_temps_scope  = old_dedup_scope; 
@@ -512,7 +524,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
512524        fake_borrow_temps :  & [ ( Place < ' tcx > ,  Local ,  FakeBorrowKind ) ] , 
513525        scrutinee_span :  Span , 
514526        arm_match_scope :  Option < ( & Arm < ' tcx > ,  region:: Scope ) > , 
515-         storages_alive :   bool , 
527+         emit_storage_live :   EmitStorageLive , 
516528    )  -> BasicBlock  { 
517529        if  candidate. subcandidates . is_empty ( )  { 
518530            // Avoid generating another `BasicBlock` when we only have one 
@@ -524,7 +536,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
524536                scrutinee_span, 
525537                arm_match_scope, 
526538                true , 
527-                 storages_alive , 
539+                 emit_storage_live , 
528540            ) 
529541        }  else  { 
530542            // It's helpful to avoid scheduling drops multiple times to save 
@@ -561,7 +573,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
561573                        scrutinee_span, 
562574                        arm_match_scope, 
563575                        schedule_drops, 
564-                         storages_alive , 
576+                         emit_storage_live , 
565577                    ) ; 
566578                    if  arm. is_none ( )  { 
567579                        schedule_drops = false ; 
@@ -731,7 +743,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
731743            & [ ] , 
732744            irrefutable_pat. span , 
733745            None , 
734-             false , 
746+             EmitStorageLive :: Yes , 
735747        ) 
736748        . unit ( ) 
737749    } 
@@ -807,6 +819,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
807819        } 
808820    } 
809821
822+     /// Emits a [`StatementKind::StorageLive`] for the given var, and also 
823+      /// schedules a drop if requested (and possible). 
810824     pub ( crate )  fn  storage_live_binding ( 
811825        & mut  self , 
812826        block :  BasicBlock , 
@@ -2034,7 +2048,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20342048        source_scope :  Option < SourceScope > , 
20352049        scope_span :  Span , 
20362050        declare_let_bindings :  DeclareLetBindings , 
2037-         storages_alive :   bool , 
2051+         emit_storage_live :   EmitStorageLive , 
20382052    )  -> BlockAnd < ( ) >  { 
20392053        let  expr_span = self . thir [ expr_id] . span ; 
20402054        let  scrutinee = unpack ! ( block = self . lower_scrutinee( block,  expr_id,  expr_span) ) ; 
@@ -2074,7 +2088,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20742088            & [ ] , 
20752089            expr_span, 
20762090            None , 
2077-             storages_alive , 
2091+             emit_storage_live , 
20782092        ) ; 
20792093
20802094        // If branch coverage is enabled, record this branch. 
@@ -2099,7 +2113,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20992113        scrutinee_span :  Span , 
21002114        arm_match_scope :  Option < ( & Arm < ' tcx > ,  region:: Scope ) > , 
21012115        schedule_drops :  bool , 
2102-         storages_alive :   bool , 
2116+         emit_storage_live :   EmitStorageLive , 
21032117    )  -> BasicBlock  { 
21042118        debug ! ( "bind_and_guard_matched_candidate(candidate={:?})" ,  candidate) ; 
21052119
@@ -2314,7 +2328,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
23142328                post_guard_block, 
23152329                true , 
23162330                by_value_bindings, 
2317-                 storages_alive , 
2331+                 emit_storage_live , 
23182332            ) ; 
23192333
23202334            post_guard_block
@@ -2326,7 +2340,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
23262340                block, 
23272341                schedule_drops, 
23282342                bindings, 
2329-                 storages_alive , 
2343+                 emit_storage_live , 
23302344            ) ; 
23312345            block
23322346        } 
@@ -2417,7 +2431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24172431        block :  BasicBlock , 
24182432        schedule_drops :  bool , 
24192433        bindings :  impl  IntoIterator < Item  = & ' b  Binding < ' tcx > > , 
2420-         storages_alive :   bool , 
2434+         emit_storage_live :   EmitStorageLive , 
24212435    )  where 
24222436        ' tcx :  ' b , 
24232437    { 
@@ -2427,19 +2441,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24272441        // Assign each of the bindings. This may trigger moves out of the candidate. 
24282442        for  binding in  bindings { 
24292443            let  source_info = self . source_info ( binding. span ) ; 
2430-             let  local = if  storages_alive  { 
2444+             let  local = match  emit_storage_live  { 
24312445                // Here storages are already alive, probably because this is a binding 
24322446                // from let-else. 
24332447                // We just need to schedule drop for the value. 
2434-                 self . var_local_id ( binding. var_id ,  OutsideGuard ) . into ( ) 
2435-             }  else  { 
2436-                 self . storage_live_binding ( 
2448+                 EmitStorageLive :: No  => self . var_local_id ( binding. var_id ,  OutsideGuard ) . into ( ) , 
2449+                 EmitStorageLive :: Yes  => self . storage_live_binding ( 
24372450                    block, 
24382451                    binding. var_id , 
24392452                    binding. span , 
24402453                    OutsideGuard , 
24412454                    schedule_drops, 
2442-                 ) 
2455+                 ) , 
24432456            } ; 
24442457            if  schedule_drops { 
24452458                self . schedule_drop_for_binding ( binding. var_id ,  binding. span ,  OutsideGuard ) ; 
0 commit comments