Skip to content

Commit 26144fe

Browse files
committed
Lowering: Fuse ExprKind::While logic + Cleanup.
1 parent 5477354 commit 26144fe

File tree

1 file changed

+54
-85
lines changed

1 file changed

+54
-85
lines changed

src/librustc/hir/lowering.rs

+54-85
Original file line numberDiff line numberDiff line change
@@ -4394,20 +4394,17 @@ impl<'a> LoweringContext<'a> {
43944394
let then_blk = self.lower_block(then, false);
43954395
let then_expr = self.expr_block(then_blk, ThinVec::new());
43964396
let (then_pats, scrutinee, desugar) = match cond.node {
4397-
// `<pat> => <then>`
4397+
// `<pat> => <then>`:
43984398
ExprKind::Let(ref pats, ref scrutinee) => {
43994399
let scrutinee = self.lower_expr(scrutinee);
44004400
let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
44014401
let desugar = hir::MatchSource::IfLetDesugar { contains_else_clause };
44024402
(pats, scrutinee, desugar)
44034403
}
4404-
// `true => then`:
4404+
// `true => <then>`:
44054405
_ => {
44064406
// Lower condition:
44074407
let cond = self.lower_expr(cond);
4408-
// Wrap in a construct equivalent to `{ let _t = $cond; _t }`
4409-
// to preserve drop semantics since `if cond { ... }`
4410-
// don't let temporaries live outside of `cond`.
44114408
let span_block = self.mark_span_with_reason(CondTemporary, cond.span, None);
44124409
// Wrap in a construct equivalent to `{ let _t = $cond; _t }`
44134410
// to preserve drop semantics since `if cond { ... }` does not
@@ -4424,61 +4421,36 @@ impl<'a> LoweringContext<'a> {
44244421
hir::ExprKind::Match(P(scrutinee), vec![then_arm, else_arm].into(), desugar)
44254422
}
44264423
// FIXME(#53667): handle lowering of && and parens.
4427-
ExprKind::While(ref cond, ref body, opt_label) => {
4428-
// Desugar `ExprWhileLet`
4429-
// from: `[opt_ident]: while let <pat> = <sub_expr> <body>`
4430-
if let ExprKind::Let(ref pats, ref sub_expr) = cond.node {
4431-
// to:
4432-
//
4433-
// [opt_ident]: loop {
4434-
// match <sub_expr> {
4435-
// <pat> => <body>,
4436-
// _ => break
4437-
// }
4438-
// }
4439-
4440-
// Note that the block AND the condition are evaluated in the loop scope.
4441-
// This is done to allow `break` from inside the condition of the loop.
4442-
let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| {
4443-
(
4444-
this.lower_block(body, false),
4445-
this.expr_break(e.span, ThinVec::new()),
4446-
this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
4447-
)
4448-
});
4424+
ExprKind::While(ref cond, ref body, opt_label) => self.with_loop_scope(e.id, |this| {
4425+
// Note that the block AND the condition are evaluated in the loop scope.
4426+
// This is done to allow `break` from inside the condition of the loop.
44494427

4450-
// `<pat> => <body>`
4451-
let pat_arm = {
4452-
let body_expr = P(self.expr_block(body, ThinVec::new()));
4453-
let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
4454-
self.arm(pats, body_expr)
4455-
};
4456-
4457-
// `_ => break`
4458-
let break_arm = {
4459-
let pat_under = self.pat_wild(e.span);
4460-
self.arm(hir_vec![pat_under], break_expr)
4461-
};
4462-
4463-
// `match <sub_expr> { ... }`
4464-
let match_expr = self.expr_match(
4465-
sub_expr.span,
4466-
sub_expr,
4467-
hir_vec![pat_arm, break_arm],
4468-
hir::MatchSource::WhileLetDesugar,
4469-
);
4428+
// `_ => break`:
4429+
let else_arm = {
4430+
let else_pat = this.pat_wild(e.span);
4431+
let else_expr = this.expr_break(e.span, ThinVec::new());
4432+
this.arm(hir_vec![else_pat], else_expr)
4433+
};
44704434

4471-
// `[opt_ident]: loop { ... }`
4472-
let loop_block = P(self.block_expr(P(match_expr)));
4473-
let loop_expr = hir::ExprKind::Loop(
4474-
loop_block,
4475-
self.lower_label(opt_label),
4476-
hir::LoopSource::WhileLet,
4477-
);
4478-
// Add attributes to the outer returned expr node.
4479-
loop_expr
4480-
} else {
4481-
self.with_loop_scope(e.id, |this| {
4435+
// Handle then + scrutinee:
4436+
let then_blk = this.lower_block(body, false);
4437+
let then_expr = this.expr_block(then_blk, ThinVec::new());
4438+
let (then_pats, scrutinee, desugar, source) = match cond.node {
4439+
ExprKind::Let(ref pats, ref scrutinee) => {
4440+
// to:
4441+
//
4442+
// [opt_ident]: loop {
4443+
// match <sub_expr> {
4444+
// <pat> => <body>,
4445+
// _ => break
4446+
// }
4447+
// }
4448+
let scrutinee = this.with_loop_condition_scope(|t| t.lower_expr(scrutinee));
4449+
let pats = pats.iter().map(|pat| this.lower_pat(pat)).collect();
4450+
let desugar = hir::MatchSource::WhileLetDesugar;
4451+
(pats, scrutinee, desugar, hir::LoopSource::WhileLet)
4452+
}
4453+
_ => {
44824454
// We desugar: `'label: while $cond $body` into:
44834455
//
44844456
// ```
@@ -4490,40 +4462,37 @@ impl<'a> LoweringContext<'a> {
44904462
// }
44914463
// ```
44924464

4493-
// `true => then`:
4494-
let then_pat = this.pat_bool(e.span, true);
4495-
let then_blk = this.lower_block(body, false);
4496-
let then_expr = this.expr_block(then_blk, ThinVec::new());
4497-
let then_arm = this.arm(hir_vec![then_pat], P(then_expr));
4498-
4499-
// `_ => break`:
4500-
let else_pat = this.pat_wild(e.span);
4501-
let else_expr = this.expr_break(e.span, ThinVec::new());
4502-
let else_arm = this.arm(hir_vec![else_pat], else_expr);
4503-
45044465
// Lower condition:
4505-
let span_block = this.mark_span_with_reason(CondTemporary, cond.span, None);
45064466
let cond = this.with_loop_condition_scope(|this| this.lower_expr(cond));
4467+
let span_block = this.mark_span_with_reason(CondTemporary, cond.span, None);
45074468
// Wrap in a construct equivalent to `{ let _t = $cond; _t }`
4508-
// to preserve drop semantics since `if cond { ... }` does not
4469+
// to preserve drop semantics since `while cond { ... }` does not
45094470
// let temporaries live outside of `cond`.
45104471
let cond = this.expr_drop_temps(span_block, P(cond), ThinVec::new());
45114472

4512-
let match_expr = this.expr_match(
4513-
cond.span,
4514-
P(cond),
4515-
vec![then_arm, else_arm].into(),
4516-
hir::MatchSource::WhileDesugar,
4517-
);
4473+
let desugar = hir::MatchSource::WhileDesugar;
4474+
// `true => <then>`:
4475+
let pats = hir_vec![this.pat_bool(e.span, true)];
4476+
(pats, cond, desugar, hir::LoopSource::While)
4477+
}
4478+
};
4479+
let then_arm = this.arm(then_pats, P(then_expr));
45184480

4519-
hir::ExprKind::Loop(
4520-
P(this.block_expr(P(match_expr))),
4521-
this.lower_label(opt_label),
4522-
hir::LoopSource::While,
4523-
)
4524-
})
4525-
}
4526-
}
4481+
// `match <scrutinee> { ... }`
4482+
let match_expr = this.expr_match(
4483+
scrutinee.span,
4484+
P(scrutinee),
4485+
hir_vec![then_arm, else_arm],
4486+
desugar,
4487+
);
4488+
4489+
// `[opt_ident]: loop { ... }`
4490+
hir::ExprKind::Loop(
4491+
P(this.block_expr(P(match_expr))),
4492+
this.lower_label(opt_label),
4493+
source
4494+
)
4495+
}),
45274496
ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
45284497
hir::ExprKind::Loop(
45294498
this.lower_block(body, false),

0 commit comments

Comments
 (0)