Skip to content

Commit 709a08a

Browse files
committed
Lower condition directly from AST to HIR
1 parent ad8b242 commit 709a08a

File tree

1 file changed

+24
-22
lines changed
  • compiler/rustc_ast_lowering/src

1 file changed

+24
-22
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+24-22
Original file line numberDiff line numberDiff line change
@@ -387,23 +387,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
387387
then: &Block,
388388
else_opt: Option<&Expr>,
389389
) -> hir::ExprKind<'hir> {
390-
let lowered_cond = self.lower_expr(cond);
391-
let new_cond = self.wrap_cond_in_drop_scope(lowered_cond);
390+
let lowered_cond = self.lower_cond(cond);
392391
let then_expr = self.lower_block_expr(then);
393392
if let Some(rslt) = else_opt {
394-
hir::ExprKind::If(new_cond, self.arena.alloc(then_expr), Some(self.lower_expr(rslt)))
393+
hir::ExprKind::If(
394+
lowered_cond,
395+
self.arena.alloc(then_expr),
396+
Some(self.lower_expr(rslt)),
397+
)
395398
} else {
396-
hir::ExprKind::If(new_cond, self.arena.alloc(then_expr), None)
399+
hir::ExprKind::If(lowered_cond, self.arena.alloc(then_expr), None)
397400
}
398401
}
399402

400-
// Wraps a condition (i.e. `cond` in `if cond` or `while cond`) in a terminating scope
403+
// Lowers a condition (i.e. `cond` in `if cond` or `while cond`), wrapping it in a terminating scope
401404
// so that temporaries created in the condition don't live beyond it.
402-
fn wrap_cond_in_drop_scope(&mut self, cond: &'hir hir::Expr<'hir>) -> &'hir hir::Expr<'hir> {
403-
fn has_let_expr<'hir>(expr: &'hir hir::Expr<'hir>) -> bool {
404-
match expr.kind {
405-
hir::ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
406-
hir::ExprKind::Let(..) => true,
405+
fn lower_cond(&mut self, cond: &Expr) -> &'hir hir::Expr<'hir> {
406+
fn has_let_expr(expr: &Expr) -> bool {
407+
match &expr.kind {
408+
ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
409+
ExprKind::Let(..) => true,
407410
_ => false,
408411
}
409412
}
@@ -415,23 +418,23 @@ impl<'hir> LoweringContext<'_, 'hir> {
415418
// In order to mantain the drop behavior for the non `let` parts of the condition,
416419
// we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially
417420
// gets transformed into `if { let _t = foo; _t } && let pat = val`
418-
match cond.kind {
419-
hir::ExprKind::Binary(
420-
op @ Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
421-
lhs,
422-
rhs,
423-
) if has_let_expr(cond) => {
424-
let lhs = self.wrap_cond_in_drop_scope(lhs);
425-
let rhs = self.wrap_cond_in_drop_scope(rhs);
421+
match &cond.kind {
422+
ExprKind::Binary(op @ Spanned { node: ast::BinOpKind::And, .. }, lhs, rhs)
423+
if has_let_expr(cond) =>
424+
{
425+
let op = self.lower_binop(*op);
426+
let lhs = self.lower_cond(lhs);
427+
let rhs = self.lower_cond(rhs);
426428

427429
self.arena.alloc(self.expr(
428430
cond.span,
429431
hir::ExprKind::Binary(op, lhs, rhs),
430432
AttrVec::new(),
431433
))
432434
}
433-
hir::ExprKind::Let(_) => cond,
435+
ExprKind::Let(..) => self.lower_expr(cond),
434436
_ => {
437+
let cond = self.lower_expr(cond);
435438
let reason = DesugaringKind::CondTemporary;
436439
let span_block = self.mark_span_with_reason(reason, cond.span, None);
437440
self.expr_drop_temps(span_block, cond, AttrVec::new())
@@ -462,14 +465,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
462465
body: &Block,
463466
opt_label: Option<Label>,
464467
) -> hir::ExprKind<'hir> {
465-
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond));
466-
let new_cond = self.wrap_cond_in_drop_scope(lowered_cond);
468+
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
467469
let then = self.lower_block_expr(body);
468470
let expr_break = self.expr_break(span, AttrVec::new());
469471
let stmt_break = self.stmt_expr(span, expr_break);
470472
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
471473
let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
472-
let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr));
474+
let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr));
473475
let if_expr = self.expr(span, if_kind, AttrVec::new());
474476
let block = self.block_expr(self.arena.alloc(if_expr));
475477
let span = self.lower_span(span.with_hi(cond.span.hi()));

0 commit comments

Comments
 (0)