Skip to content

Commit 686da48

Browse files
committed
de-duplicate condition scoping logic
1 parent 5e749eb commit 686da48

File tree

3 files changed

+10
-28
lines changed

3 files changed

+10
-28
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -547,15 +547,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
547547

548548
// Lowers a condition (i.e. `cond` in `if cond` or `while cond`), wrapping it in a terminating scope
549549
// so that temporaries created in the condition don't live beyond it.
550-
fn lower_cond(&mut self, cond: &Expr) -> &'hir hir::Expr<'hir> {
551-
fn has_let_expr(expr: &Expr) -> bool {
552-
match &expr.kind {
553-
ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
554-
ExprKind::Let(..) => true,
555-
_ => false,
556-
}
557-
}
558-
550+
pub(super) fn lower_cond(&mut self, cond: &Expr) -> &'hir hir::Expr<'hir> {
559551
// We have to take special care for `let` exprs in the condition, e.g. in
560552
// `if let pat = val` or `if foo && let pat = val`, as we _do_ want `val` to live beyond the
561553
// condition in this case.
@@ -564,14 +556,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
564556
// we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially
565557
// gets transformed into `if { let _t = foo; _t } && let pat = val`
566558
match &cond.kind {
567-
ExprKind::Binary(op @ Spanned { node: ast::BinOpKind::And, .. }, lhs, rhs)
568-
if has_let_expr(cond) =>
569-
{
570-
let op = self.lower_binop(*op);
571-
let lhs = self.lower_cond(lhs);
572-
let rhs = self.lower_cond(rhs);
573-
574-
self.arena.alloc(self.expr(cond.span, hir::ExprKind::Binary(op, lhs, rhs)))
559+
ExprKind::Binary(BinOp { node: BinOpKind::And | BinOpKind::Or, .. }, _, _) => {
560+
// Terminating scopes for logical `&&` and `||` are handled in
561+
// `rustc_hir_analysis::check::region::resolve_expr`; see the comment there.
562+
self.lower_expr(cond)
575563
}
576564
ExprKind::Let(..) => self.lower_expr(cond),
577565
_ => {
@@ -675,7 +663,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
675663

676664
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
677665
let pat = self.lower_pat(&arm.pat);
678-
let guard = arm.guard.as_ref().map(|cond| self.lower_expr(cond));
666+
let guard = arm.guard.as_ref().map(|cond| self.lower_cond(cond));
679667
let hir_id = self.next_id();
680668
let span = self.lower_span(arm.span);
681669
self.lower_attrs(hir_id, &arm.attrs, arm.span);

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
134134
);
135135
}
136136
PatKind::Guard(inner, cond) => {
137-
break hir::PatKind::Guard(self.lower_pat(inner), self.lower_expr(cond));
137+
break hir::PatKind::Guard(self.lower_pat(inner), self.lower_cond(cond));
138138
}
139139
PatKind::Slice(pats) => break self.lower_pat_slice(pats),
140140
PatKind::Rest => {

compiler/rustc_hir_analysis/src/check/region.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,22 +177,16 @@ fn resolve_block<'tcx>(
177177
}
178178

179179
fn resolve_arm<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, arm: &'tcx hir::Arm<'tcx>) {
180-
fn has_let_expr(expr: &Expr<'_>) -> bool {
181-
match &expr.kind {
182-
hir::ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
183-
hir::ExprKind::Let(..) => true,
184-
_ => false,
185-
}
186-
}
187-
188180
let prev_cx = visitor.cx;
189181

190182
visitor.enter_node_scope_with_dtor(arm.hir_id.local_id, true);
191183
visitor.cx.var_parent = visitor.cx.parent;
192184

193185
resolve_pat(visitor, arm.pat);
194186
if let Some(guard) = arm.guard {
195-
resolve_expr(visitor, guard, !has_let_expr(guard));
187+
// If the guard should be a terminating scope (i.e. it has no `let` expressions), it will
188+
// have been wrapped in a `DropTemps` expression during AST -> HIR lowering.
189+
resolve_expr(visitor, guard, false);
196190
}
197191
resolve_expr(visitor, arm.body, false);
198192

0 commit comments

Comments
 (0)