Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit cc5664c

Browse files
committed
Add rustc comment into while desugaring
1 parent 3115d69 commit cc5664c

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

crates/hir-def/src/body/lower.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -313,20 +313,7 @@ impl ExprCollector<'_> {
313313
let body = self.collect_labelled_block_opt(label, e.loop_body());
314314
self.alloc_expr(Expr::Loop { body, label }, syntax_ptr)
315315
}
316-
ast::Expr::WhileExpr(e) => {
317-
// Desugar `while <cond> { <body> }` to
318-
// `loop { if <cond> { <body> } else { break } }`
319-
let label = e.label().map(|label| self.collect_label(label));
320-
let body = self.collect_labelled_block_opt(label, e.loop_body());
321-
let condition = self.collect_expr_opt(e.condition());
322-
let break_expr =
323-
self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr.clone());
324-
let if_expr = self.alloc_expr(
325-
Expr::If { condition, then_branch: body, else_branch: Some(break_expr) },
326-
syntax_ptr.clone(),
327-
);
328-
self.alloc_expr(Expr::Loop { body: if_expr, label }, syntax_ptr)
329-
}
316+
ast::Expr::WhileExpr(e) => self.collect_while_loop(syntax_ptr, e),
330317
ast::Expr::ForExpr(e) => self.collect_for_loop(syntax_ptr, e),
331318
ast::Expr::CallExpr(e) => {
332319
let is_rustc_box = {
@@ -738,6 +725,32 @@ impl ExprCollector<'_> {
738725
expr_id
739726
}
740727

728+
/// Desugar `ast::WhileExpr` from: `[opt_ident]: while <cond> <body>` into:
729+
/// ```ignore (pseudo-rust)
730+
/// [opt_ident]: loop {
731+
/// if <cond> {
732+
/// <body>
733+
/// }
734+
/// else {
735+
/// break;
736+
/// }
737+
/// }
738+
/// ```
739+
/// FIXME: Rustc wraps the condition in a construct equivalent to `{ let _t = <cond>; _t }`
740+
/// to preserve drop semantics. We should probably do the same in future.
741+
fn collect_while_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::WhileExpr) -> ExprId {
742+
let label = e.label().map(|label| self.collect_label(label));
743+
let body = self.collect_labelled_block_opt(label, e.loop_body());
744+
let condition = self.collect_expr_opt(e.condition());
745+
let break_expr =
746+
self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr.clone());
747+
let if_expr = self.alloc_expr(
748+
Expr::If { condition, then_branch: body, else_branch: Some(break_expr) },
749+
syntax_ptr.clone(),
750+
);
751+
self.alloc_expr(Expr::Loop { body: if_expr, label }, syntax_ptr)
752+
}
753+
741754
/// Desugar `ast::ForExpr` from: `[opt_ident]: for <pat> in <head> <body>` into:
742755
/// ```ignore (pseudo-rust)
743756
/// match IntoIterator::into_iter(<head>) {

0 commit comments

Comments
 (0)