diff options
| author | Ding Xiang Fei <dingxiangfei2009@protonmail.ch> | 2022-09-16 19:02:45 +0800 |
|---|---|---|
| committer | Ding Xiang Fei <dingxiangfei2009@protonmail.ch> | 2022-09-18 12:10:53 +0800 |
| commit | 48c1c1d19043120e9e89b3186d5d5286142f3066 (patch) | |
| tree | b7d1b915eff1b63dc22f4a6738dd7ce1f60d5fdd | |
| parent | bc7b17cfe3bf08b618d1c7b64838053faeb1f590 (diff) | |
| download | rust-48c1c1d19043120e9e89b3186d5d5286142f3066.tar.gz rust-48c1c1d19043120e9e89b3186d5d5286142f3066.zip | |
avoid duplicating StorageLive in let-else
| -rw-r--r-- | compiler/rustc_mir_build/src/build/block.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/matches/mod.rs | 39 |
2 files changed, 33 insertions, 9 deletions
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 7ab7870c464..4bab583c960 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -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!( diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index e0727725f68..82067ceebfd 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -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 { @@ -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 @@ -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 @@ -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; @@ -641,6 +645,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, None, None, + false, ) .unit() } @@ -1813,6 +1818,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, None, None, + false, ); post_guard_block.unit() @@ -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); @@ -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 { @@ -2065,6 +2077,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .iter() .flat_map(|(bindings, _)| bindings) .chain(&candidate.bindings), + storages_alive, ); block } @@ -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, { @@ -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); } @@ -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( @@ -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() |
