Skip to content

Commit ff49c37

Browse files
committed
Reuse lower_let_expr for let .. else lowering
1 parent 7b150a1 commit ff49c37

File tree

2 files changed

+49
-87
lines changed

2 files changed

+49
-87
lines changed

compiler/rustc_mir_build/src/build/block.rs

+31-32
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

+18-55
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;
@@ -1981,48 +1982,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19811982

19821983
impl<'a, 'tcx> Builder<'a, 'tcx> {
19831984
/// If the bindings have already been declared, set `declare_bindings` to
1984-
/// `false` to avoid duplicated bindings declaration. Used for if-let guards.
1985+
/// `false` to avoid duplicated bindings declaration; used for if-let guards.
19851986
pub(crate) fn lower_let_expr(
19861987
&mut self,
19871988
mut block: BasicBlock,
19881989
expr_id: ExprId,
19891990
pat: &Pat<'tcx>,
19901991
source_scope: Option<SourceScope>,
1991-
span: Span,
1992+
scope_span: Span,
19921993
declare_bindings: bool,
1994+
storages_alive: bool,
19931995
) -> BlockAnd<()> {
19941996
let expr_span = self.thir[expr_id].span;
1995-
let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span));
1996-
let mut guard_candidate = Candidate::new(expr_place_builder.clone(), pat, false, self);
1997+
let scrutinee = unpack!(block = self.lower_scrutinee(block, expr_id, expr_span));
1998+
let mut candidate = Candidate::new(scrutinee.clone(), pat, false, self);
19971999
let otherwise_block = self.lower_match_tree(
19982000
block,
2001+
expr_span,
2002+
&scrutinee,
19992003
pat.span,
2000-
&expr_place_builder,
2001-
pat.span,
2002-
&mut [&mut guard_candidate],
2004+
&mut [&mut candidate],
20032005
true,
20042006
);
2005-
let expr_place = expr_place_builder.try_to_place(self);
2006-
let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span));
2007+
20072008
self.break_for_else(otherwise_block, self.source_info(expr_span));
20082009

20092010
if declare_bindings {
2010-
self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place);
2011+
let expr_place = scrutinee.try_to_place(self);
2012+
let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span));
2013+
self.declare_bindings(source_scope, pat.span.to(scope_span), pat, None, opt_expr_place);
20112014
}
20122015

2013-
let post_guard_block = self.bind_pattern(
2016+
let success = self.bind_pattern(
20142017
self.source_info(pat.span),
2015-
guard_candidate,
2018+
candidate,
20162019
&[],
20172020
expr_span,
20182021
None,
2019-
false,
2022+
storages_alive,
20202023
);
20212024

20222025
// If branch coverage is enabled, record this branch.
2023-
self.visit_coverage_conditional_let(pat, post_guard_block, otherwise_block);
2026+
self.visit_coverage_conditional_let(pat, success, otherwise_block);
20242027

2025-
post_guard_block.unit()
2028+
success.unit()
20262029
}
20272030

20282031
/// Initializes each of the bindings from the candidate by
@@ -2469,44 +2472,4 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
24692472
debug!(?locals);
24702473
self.var_indices.insert(var_id, locals);
24712474
}
2472-
2473-
pub(crate) fn ast_let_else(
2474-
&mut self,
2475-
mut block: BasicBlock,
2476-
init_id: ExprId,
2477-
initializer_span: Span,
2478-
else_block: BlockId,
2479-
let_else_scope: &region::Scope,
2480-
pattern: &Pat<'tcx>,
2481-
) -> BlockAnd<BasicBlock> {
2482-
let else_block_span = self.thir[else_block].span;
2483-
let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| {
2484-
let scrutinee = unpack!(block = this.lower_scrutinee(block, init_id, initializer_span));
2485-
let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this);
2486-
let failure_block = this.lower_match_tree(
2487-
block,
2488-
initializer_span,
2489-
&scrutinee,
2490-
pattern.span,
2491-
&mut [&mut candidate],
2492-
true,
2493-
);
2494-
// This block is for the matching case
2495-
let matching = this.bind_pattern(
2496-
this.source_info(pattern.span),
2497-
candidate,
2498-
&[],
2499-
initializer_span,
2500-
None,
2501-
true,
2502-
);
2503-
2504-
// If branch coverage is enabled, record this branch.
2505-
this.visit_coverage_conditional_let(pattern, matching, failure_block);
2506-
2507-
this.break_for_else(failure_block, this.source_info(initializer_span));
2508-
matching.unit()
2509-
});
2510-
matching.and(failure)
2511-
}
25122475
}

0 commit comments

Comments
 (0)