From 48c1c1d19043120e9e89b3186d5d5286142f3066 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Fri, 16 Sep 2022 19:02:45 +0800 Subject: [PATCH] avoid duplicating StorageLive in let-else --- compiler/rustc_mir_build/src/build/block.rs | 3 +- .../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 @@ fn ast_block_stmts( 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 @@ fn lower_match_arms( Some(arm.span), Some(arm.scope), Some(match_scope), + false, ); if let Some(source_scope) = scope { @@ -416,6 +417,7 @@ fn bind_pattern( arm_span: Option, arm_scope: Option, match_scope: Option, + storages_alive: bool, ) -> BasicBlock { if candidate.subcandidates.is_empty() { // Avoid generating another `BasicBlock` when we only have one @@ -429,6 +431,7 @@ fn bind_pattern( arm_span, match_scope, true, + storages_alive, ) } else { // It's helpful to avoid scheduling drops multiple times to save @@ -466,6 +469,7 @@ fn bind_pattern( arm_span, match_scope, schedule_drops, + storages_alive, ); if arm_scope.is_none() { schedule_drops = false; @@ -641,6 +645,7 @@ pub(crate) fn place_into_pattern( None, None, None, + false, ) .unit() } @@ -1813,6 +1818,7 @@ pub(crate) fn lower_let_expr( None, None, None, + false, ); post_guard_block.unit() @@ -1836,6 +1842,7 @@ fn bind_and_guard_matched_candidate<'pat>( arm_span: Option, match_scope: Option, schedule_drops: bool, + storages_alive: bool, ) -> BasicBlock { debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate); @@ -2051,7 +2058,12 @@ fn bind_and_guard_matched_candidate<'pat>( 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 @@ fn bind_and_guard_matched_candidate<'pat>( .iter() .flat_map(|(bindings, _)| bindings) .chain(&candidate.bindings), + storages_alive, ); block } @@ -2154,6 +2167,7 @@ fn bind_matched_candidate_for_arm_body<'b>( block: BasicBlock, schedule_drops: bool, bindings: impl IntoIterator>, + storages_alive: bool, ) where 'tcx: 'b, { @@ -2163,13 +2177,20 @@ fn bind_matched_candidate_for_arm_body<'b>( // 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 @@ pub(crate) fn ast_let_else( None, None, None, + true, ); // This block is for the failure case let failure = this.bind_pattern( @@ -2311,6 +2333,7 @@ pub(crate) fn ast_let_else( None, None, None, + true, ); this.break_for_else(failure, *let_else_scope, this.source_info(initializer_span)); matching.unit()