@@ -371,6 +371,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
371
371
Some ( arm. span ) ,
372
372
Some ( arm. scope ) ,
373
373
Some ( match_scope) ,
374
+ false ,
374
375
) ;
375
376
376
377
if let Some ( source_scope) = scope {
@@ -416,6 +417,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
416
417
arm_span : Option < Span > ,
417
418
arm_scope : Option < region:: Scope > ,
418
419
match_scope : Option < region:: Scope > ,
420
+ storages_alive : bool ,
419
421
) -> BasicBlock {
420
422
if candidate. subcandidates . is_empty ( ) {
421
423
// Avoid generating another `BasicBlock` when we only have one
@@ -429,6 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
429
431
arm_span,
430
432
match_scope,
431
433
true ,
434
+ storages_alive,
432
435
)
433
436
} else {
434
437
// It's helpful to avoid scheduling drops multiple times to save
@@ -466,6 +469,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
466
469
arm_span,
467
470
match_scope,
468
471
schedule_drops,
472
+ storages_alive,
469
473
) ;
470
474
if arm_scope. is_none ( ) {
471
475
schedule_drops = false ;
@@ -641,6 +645,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
641
645
None ,
642
646
None ,
643
647
None ,
648
+ false ,
644
649
)
645
650
. unit ( )
646
651
}
@@ -1813,6 +1818,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1813
1818
None ,
1814
1819
None ,
1815
1820
None ,
1821
+ false ,
1816
1822
) ;
1817
1823
1818
1824
post_guard_block. unit ( )
@@ -1836,6 +1842,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1836
1842
arm_span : Option < Span > ,
1837
1843
match_scope : Option < region:: Scope > ,
1838
1844
schedule_drops : bool ,
1845
+ storages_alive : bool ,
1839
1846
) -> BasicBlock {
1840
1847
debug ! ( "bind_and_guard_matched_candidate(candidate={:?})" , candidate) ;
1841
1848
@@ -2051,7 +2058,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2051
2058
self . cfg . push_fake_read ( post_guard_block, guard_end, cause, Place :: from ( local_id) ) ;
2052
2059
}
2053
2060
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
+ ) ;
2055
2067
2056
2068
post_guard_block
2057
2069
} else {
@@ -2065,6 +2077,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2065
2077
. iter ( )
2066
2078
. flat_map ( |( bindings, _) | bindings)
2067
2079
. chain ( & candidate. bindings ) ,
2080
+ storages_alive,
2068
2081
) ;
2069
2082
block
2070
2083
}
@@ -2154,6 +2167,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2154
2167
block : BasicBlock ,
2155
2168
schedule_drops : bool ,
2156
2169
bindings : impl IntoIterator < Item = & ' b Binding < ' tcx > > ,
2170
+ storages_alive : bool ,
2157
2171
) where
2158
2172
' tcx : ' b ,
2159
2173
{
@@ -2163,13 +2177,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2163
2177
// Assign each of the bindings. This may trigger moves out of the candidate.
2164
2178
for binding in bindings {
2165
2179
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
+ } ;
2173
2194
if schedule_drops {
2174
2195
self . schedule_drop_for_binding ( binding. var_id , binding. span , OutsideGuard ) ;
2175
2196
}
@@ -2300,6 +2321,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2300
2321
None ,
2301
2322
None ,
2302
2323
None ,
2324
+ true ,
2303
2325
) ;
2304
2326
// This block is for the failure case
2305
2327
let failure = this. bind_pattern (
@@ -2311,6 +2333,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2311
2333
None ,
2312
2334
None ,
2313
2335
None ,
2336
+ true ,
2314
2337
) ;
2315
2338
this. break_for_else ( failure, * let_else_scope, this. source_info ( initializer_span) ) ;
2316
2339
matching. unit ( )
0 commit comments