@@ -371,6 +371,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
371371 Some ( arm. span ) ,
372372 Some ( arm. scope ) ,
373373 Some ( match_scope) ,
374+ false ,
374375 ) ;
375376
376377 if let Some ( source_scope) = scope {
@@ -416,6 +417,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
416417 arm_span : Option < Span > ,
417418 arm_scope : Option < region:: Scope > ,
418419 match_scope : Option < region:: Scope > ,
420+ storages_alive : bool ,
419421 ) -> BasicBlock {
420422 if candidate. subcandidates . is_empty ( ) {
421423 // Avoid generating another `BasicBlock` when we only have one
@@ -429,6 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
429431 arm_span,
430432 match_scope,
431433 true ,
434+ storages_alive,
432435 )
433436 } else {
434437 // It's helpful to avoid scheduling drops multiple times to save
@@ -466,6 +469,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
466469 arm_span,
467470 match_scope,
468471 schedule_drops,
472+ storages_alive,
469473 ) ;
470474 if arm_scope. is_none ( ) {
471475 schedule_drops = false ;
@@ -641,6 +645,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
641645 None ,
642646 None ,
643647 None ,
648+ false ,
644649 )
645650 . unit ( )
646651 }
@@ -1813,6 +1818,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
18131818 None ,
18141819 None ,
18151820 None ,
1821+ false ,
18161822 ) ;
18171823
18181824 post_guard_block. unit ( )
@@ -1836,6 +1842,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
18361842 arm_span : Option < Span > ,
18371843 match_scope : Option < region:: Scope > ,
18381844 schedule_drops : bool ,
1845+ storages_alive : bool ,
18391846 ) -> BasicBlock {
18401847 debug ! ( "bind_and_guard_matched_candidate(candidate={:?})" , candidate) ;
18411848
@@ -2051,7 +2058,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20512058 self . cfg . push_fake_read ( post_guard_block, guard_end, cause, Place :: from ( local_id) ) ;
20522059 }
20532060 assert ! ( schedule_drops, "patterns with guards must schedule drops" ) ;
2054- self . bind_matched_candidate_for_arm_body ( post_guard_block, true , by_value_bindings) ;
2061+ self . bind_matched_candidate_for_arm_body (
2062+ post_guard_block,
2063+ true ,
2064+ by_value_bindings,
2065+ storages_alive,
2066+ ) ;
20552067
20562068 post_guard_block
20572069 } else {
@@ -2065,6 +2077,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
20652077 . iter ( )
20662078 . flat_map ( |( bindings, _) | bindings)
20672079 . chain ( & candidate. bindings ) ,
2080+ storages_alive,
20682081 ) ;
20692082 block
20702083 }
@@ -2154,6 +2167,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21542167 block : BasicBlock ,
21552168 schedule_drops : bool ,
21562169 bindings : impl IntoIterator < Item = & ' b Binding < ' tcx > > ,
2170+ storages_alive : bool ,
21572171 ) where
21582172 ' tcx : ' b ,
21592173 {
@@ -2163,13 +2177,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
21632177 // Assign each of the bindings. This may trigger moves out of the candidate.
21642178 for binding in bindings {
21652179 let source_info = self . source_info ( binding. span ) ;
2166- let local = self . storage_live_binding (
2167- block,
2168- binding. var_id ,
2169- binding. span ,
2170- OutsideGuard ,
2171- schedule_drops,
2172- ) ;
2180+ let local = if storages_alive {
2181+ // Here storages are already alive, probably because this is a binding
2182+ // from let-else.
2183+ // We just need to schedule drop for the value.
2184+ self . var_local_id ( binding. var_id , OutsideGuard ) . into ( )
2185+ } else {
2186+ self . storage_live_binding (
2187+ block,
2188+ binding. var_id ,
2189+ binding. span ,
2190+ OutsideGuard ,
2191+ schedule_drops,
2192+ )
2193+ } ;
21732194 if schedule_drops {
21742195 self . schedule_drop_for_binding ( binding. var_id , binding. span , OutsideGuard ) ;
21752196 }
@@ -2300,6 +2321,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
23002321 None ,
23012322 None ,
23022323 None ,
2324+ true ,
23032325 ) ;
23042326 // This block is for the failure case
23052327 let failure = this. bind_pattern (
@@ -2311,6 +2333,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
23112333 None ,
23122334 None ,
23132335 None ,
2336+ true ,
23142337 ) ;
23152338 this. break_for_else ( failure, * let_else_scope, this. source_info ( initializer_span) ) ;
23162339 matching. unit ( )
0 commit comments