Skip to content

Commit d426a45

Browse files
committed
Lowering: Fuse ExprKind::While logic + Cleanup.
1 parent 4bdfd96 commit d426a45

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
@@ -4392,20 +4392,17 @@ impl<'a> LoweringContext<'a> {
43924392
let then_blk = self.lower_block(then, false);
43934393
let then_expr = self.expr_block(then_blk, ThinVec::new());
43944394
let (then_pats, scrutinee, desugar) = match cond.node {
4395-
// `<pat> => <then>`
4395+
// `<pat> => <then>`:
43964396
ExprKind::Let(ref pats, ref scrutinee) => {
43974397
let scrutinee = self.lower_expr(scrutinee);
43984398
let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
43994399
let desugar = hir::MatchSource::IfLetDesugar { contains_else_clause };
44004400
(pats, scrutinee, desugar)
44014401
}
4402-
// `true => then`:
4402+
// `true => <then>`:
44034403
_ => {
44044404
// Lower condition:
44054405
let cond = self.lower_expr(cond);
4406-
// Wrap in a construct equivalent to `{ let _t = $cond; _t }`
4407-
// to preserve drop semantics since `if cond { ... }`
4408-
// don't let temporaries live outside of `cond`.
44094406
let span_block = self.mark_span_with_reason(CondTemporary, cond.span, None);
44104407
// Wrap in a construct equivalent to `{ let _t = $cond; _t }`
44114408
// to preserve drop semantics since `if cond { ... }` does not
@@ -4422,61 +4419,36 @@ impl<'a> LoweringContext<'a> {
44224419
hir::ExprKind::Match(P(scrutinee), vec![then_arm, else_arm].into(), desugar)
44234420
}
44244421
// FIXME(#53667): handle lowering of && and parens.
4425-
ExprKind::While(ref cond, ref body, opt_label) => {
4426-
// Desugar `ExprWhileLet`
4427-
// from: `[opt_ident]: while let <pat> = <sub_expr> <body>`
4428-
if let ExprKind::Let(ref pats, ref sub_expr) = cond.node {
4429-
// to:
4430-
//
4431-
// [opt_ident]: loop {
4432-
// match <sub_expr> {
4433-
// <pat> => <body>,
4434-
// _ => break
4435-
// }
4436-
// }
4437-
4438-
// Note that the block AND the condition are evaluated in the loop scope.
4439-
// This is done to allow `break` from inside the condition of the loop.
4440-
let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| {
4441-
(
4442-
this.lower_block(body, false),
4443-
this.expr_break(e.span, ThinVec::new()),
4444-
this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
4445-
)
4446-
});
4422+
ExprKind::While(ref cond, ref body, opt_label) => self.with_loop_scope(e.id, |this| {
4423+
// Note that the block AND the condition are evaluated in the loop scope.
4424+
// This is done to allow `break` from inside the condition of the loop.
44474425

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

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

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

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

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

0 commit comments

Comments
 (0)