Skip to content

Commit

Permalink
avoid duplicating StorageLive in let-else
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Sep 18, 2022
1 parent bc7b17c commit 48c1c1d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_mir_build/src/build/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pattern,
UserTypeProjections::none(),
&mut |this, _, _, _, node, span, _, _| {
this.storage_live_binding(block, node, span, OutsideGuard, false);
this.storage_live_binding(block, node, span, OutsideGuard, true);
this.schedule_drop_for_binding(node, span, OutsideGuard);
},
);
let failure = unpack!(
Expand Down
39 changes: 31 additions & 8 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Some(arm.span),
Some(arm.scope),
Some(match_scope),
false,
);

if let Some(source_scope) = scope {
Expand Down Expand Up @@ -416,6 +417,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span: Option<Span>,
arm_scope: Option<region::Scope>,
match_scope: Option<region::Scope>,
storages_alive: bool,
) -> BasicBlock {
if candidate.subcandidates.is_empty() {
// Avoid generating another `BasicBlock` when we only have one
Expand All @@ -429,6 +431,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span,
match_scope,
true,
storages_alive,
)
} else {
// It's helpful to avoid scheduling drops multiple times to save
Expand Down Expand Up @@ -466,6 +469,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span,
match_scope,
schedule_drops,
storages_alive,
);
if arm_scope.is_none() {
schedule_drops = false;
Expand Down Expand Up @@ -641,6 +645,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
false,
)
.unit()
}
Expand Down Expand Up @@ -1813,6 +1818,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
false,
);

post_guard_block.unit()
Expand All @@ -1836,6 +1842,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
arm_span: Option<Span>,
match_scope: Option<region::Scope>,
schedule_drops: bool,
storages_alive: bool,
) -> BasicBlock {
debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);

Expand Down Expand Up @@ -2051,7 +2058,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.cfg.push_fake_read(post_guard_block, guard_end, cause, Place::from(local_id));
}
assert!(schedule_drops, "patterns with guards must schedule drops");
self.bind_matched_candidate_for_arm_body(post_guard_block, true, by_value_bindings);
self.bind_matched_candidate_for_arm_body(
post_guard_block,
true,
by_value_bindings,
storages_alive,
);

post_guard_block
} else {
Expand All @@ -2065,6 +2077,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.iter()
.flat_map(|(bindings, _)| bindings)
.chain(&candidate.bindings),
storages_alive,
);
block
}
Expand Down Expand Up @@ -2154,6 +2167,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block: BasicBlock,
schedule_drops: bool,
bindings: impl IntoIterator<Item = &'b Binding<'tcx>>,
storages_alive: bool,
) where
'tcx: 'b,
{
Expand All @@ -2163,13 +2177,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Assign each of the bindings. This may trigger moves out of the candidate.
for binding in bindings {
let source_info = self.source_info(binding.span);
let local = self.storage_live_binding(
block,
binding.var_id,
binding.span,
OutsideGuard,
schedule_drops,
);
let local = if storages_alive {
// Here storages are already alive, probably because this is a binding
// from let-else.
// We just need to schedule drop for the value.
self.var_local_id(binding.var_id, OutsideGuard).into()
} else {
self.storage_live_binding(
block,
binding.var_id,
binding.span,
OutsideGuard,
schedule_drops,
)
};
if schedule_drops {
self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard);
}
Expand Down Expand Up @@ -2300,6 +2321,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
true,
);
// This block is for the failure case
let failure = this.bind_pattern(
Expand All @@ -2311,6 +2333,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
None,
None,
None,
true,
);
this.break_for_else(failure, *let_else_scope, this.source_info(initializer_span));
matching.unit()
Expand Down

0 comments on commit 48c1c1d

Please sign in to comment.