Skip to content

Commit 7832ba7

Browse files
NadrierilZalathar
authored andcommitted
Reuse lower_let_expr for let .. else lowering
1 parent 762e81f commit 7832ba7

File tree

2 files changed

+49
-87
lines changed

2 files changed

+49
-87
lines changed

compiler/rustc_mir_build/src/build/block.rs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -189,38 +189,37 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
189189

190190
let initializer_span = this.thir[*initializer].span;
191191
let scope = (*init_scope, source_info);
192-
let failure = unpack!(
193-
block = this.in_scope(scope, *lint_level, |this| {
194-
this.declare_bindings(
195-
visibility_scope,
196-
remainder_span,
197-
pattern,
198-
None,
199-
Some((Some(&destination), initializer_span)),
200-
);
201-
this.visit_primary_bindings(
202-
pattern,
203-
UserTypeProjections::none(),
204-
&mut |this, _, _, node, span, _, _| {
205-
this.storage_live_binding(
206-
block,
207-
node,
208-
span,
209-
OutsideGuard,
210-
true,
211-
);
212-
},
213-
);
214-
this.ast_let_else(
215-
block,
216-
*initializer,
217-
initializer_span,
218-
*else_block,
219-
&last_remainder_scope,
220-
pattern,
221-
)
222-
})
223-
);
192+
let failure_and_block = this.in_scope(scope, *lint_level, |this| {
193+
this.declare_bindings(
194+
visibility_scope,
195+
remainder_span,
196+
pattern,
197+
None,
198+
Some((Some(&destination), initializer_span)),
199+
);
200+
this.visit_primary_bindings(
201+
pattern,
202+
UserTypeProjections::none(),
203+
&mut |this, _, _, node, span, _, _| {
204+
this.storage_live_binding(block, node, span, OutsideGuard, true);
205+
},
206+
);
207+
let else_block_span = this.thir[*else_block].span;
208+
let (matching, failure) =
209+
this.in_if_then_scope(last_remainder_scope, else_block_span, |this| {
210+
this.lower_let_expr(
211+
block,
212+
*initializer,
213+
pattern,
214+
None,
215+
initializer_span,
216+
false,
217+
true,
218+
)
219+
});
220+
matching.and(failure)
221+
});
222+
let failure = unpack!(block = failure_and_block);
224223
this.cfg.goto(failure, source_info, failure_entry);
225224

226225
if let Some(source_scope) = visibility_scope {

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

Lines changed: 18 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
147147
Some(args.variable_source_info.scope),
148148
args.variable_source_info.span,
149149
args.declare_let_bindings,
150+
false,
150151
),
151152
_ => {
152153
let mut block = block;
@@ -1995,48 +1996,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19951996

19961997
impl<'a, 'tcx> Builder<'a, 'tcx> {
19971998
/// If the bindings have already been declared, set `declare_bindings` to
1998-
/// `false` to avoid duplicated bindings declaration. Used for if-let guards.
1999+
/// `false` to avoid duplicated bindings declaration; used for if-let guards.
19992000
pub(crate) fn lower_let_expr(
20002001
&mut self,
20012002
mut block: BasicBlock,
20022003
expr_id: ExprId,
20032004
pat: &Pat<'tcx>,
20042005
source_scope: Option<SourceScope>,
2005-
span: Span,
2006+
scope_span: Span,
20062007
declare_bindings: bool,
2008+
storages_alive: bool,
20072009
) -> BlockAnd<()> {
20082010
let expr_span = self.thir[expr_id].span;
2009-
let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span));
2010-
let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self);
2011+
let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span));
2012+
let mut candidate = Candidate::new(scrutinee.clone(), pat, false, self);
20112013
let otherwise_block = self.lower_match_tree(
20122014
block,
2015+
expr_span,
2016+
&scrutinee,
20132017
pat.span,
2014-
&expr_place_builder,
2015-
pat.span,
2016-
&mut [&mut guard_candidate],
2018+
&mut [&mut candidate],
20172019
true,
20182020
);
2019-
let expr_place = expr_place_builder.try_to_place(self);
2020-
let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span));
2021+
20212022
self.break_for_else(otherwise_block, self.source_info(expr_span));
20222023

20232024
if declare_bindings {
2024-
self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place);
2025+
let expr_place = scrutinee.try_to_place(self);
2026+
let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span));
2027+
self.declare_bindings(source_scope, pat.span.to(scope_span), pat, None, opt_expr_place);
20252028
}
20262029

2027-
let post_guard_block = self.bind_pattern(
2030+
let success = self.bind_pattern(
20282031
self.source_info(pat.span),
2029-
guard_candidate,
2032+
candidate,
20302033
&[],
20312034
expr_span,
20322035
None,
2033-
false,
2036+
storages_alive,
20342037
);
20352038

20362039
// If branch coverage is enabled, record this branch.
2037-
self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_block);
2040+
self.visit_coverage_conditional_let(pat, success, otherwise_block);
20382041

2039-
post_guard_block.unit()
2042+
success.unit()
20402043
}
20412044

20422045
/// Initializes each of the bindings from the candidate by
@@ -2483,44 +2486,4 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24832486
debug!(?locals);
24842487
self.var_indices.insert(var_id, locals);
24852488
}
2486-
2487-
pub(crate) fn ast_let_else(
2488-
&mut self,
2489-
mut block: BasicBlock,
2490-
init_id: ExprId,
2491-
initializer_span: Span,
2492-
else_block: BlockId,
2493-
let_else_scope: &region::Scope,
2494-
pattern: &Pat<'tcx>,
2495-
) -> BlockAnd<BasicBlock> {
2496-
let else_block_span = self.thir[else_block].span;
2497-
let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| {
2498-
let scrutinee = unpack!(block = this.lower_scrutinee(block, init_id, initializer_span));
2499-
let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this);
2500-
let failure_block = this.lower_match_tree(
2501-
block,
2502-
initializer_span,
2503-
&scrutinee,
2504-
pattern.span,
2505-
&mut [&mut candidate],
2506-
true,
2507-
);
2508-
// This block is for the matching case
2509-
let matching = this.bind_pattern(
2510-
this.source_info(pattern.span),
2511-
candidate,
2512-
&[],
2513-
initializer_span,
2514-
None,
2515-
true,
2516-
);
2517-
2518-
// If branch coverage is enabled, record this branch.
2519-
this.visit_coverage_conditional_let(pattern, matching, failure_block);
2520-
2521-
this.break_for_else(failure_block, this.source_info(initializer_span));
2522-
matching.unit()
2523-
});
2524-
matching.and(failure)
2525-
}
25262489
}

0 commit comments

Comments
 (0)