Skip to content

Commit 48c1c1d

Browse files
avoid duplicating StorageLive in let-else
1 parent bc7b17c commit 48c1c1d

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

compiler/rustc_mir_build/src/build/block.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
232232
pattern,
233233
UserTypeProjections::none(),
234234
&mut |this, _, _, _, node, span, _, _| {
235-
this.storage_live_binding(block, node, span, OutsideGuard, false);
235+
this.storage_live_binding(block, node, span, OutsideGuard, true);
236+
this.schedule_drop_for_binding(node, span, OutsideGuard);
236237
},
237238
);
238239
let failure = unpack!(

compiler/rustc_mir_build/src/build/matches/mod.rs

+31-8
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)