Skip to content

Commit 31bcba8

Browse files
committed
hir: Desugar while to loop and break
1 parent 151c750 commit 31bcba8

File tree

4 files changed

+21
-2
lines changed

4 files changed

+21
-2
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,18 @@ impl ExprCollector<'_> {
314314
self.alloc_expr(Expr::Loop { body, label }, syntax_ptr)
315315
}
316316
ast::Expr::WhileExpr(e) => {
317+
// Desugar `while <cond> { <body> }` to
318+
// `loop { if <cond> { <body> } else { break } }`
317319
let label = e.label().map(|label| self.collect_label(label));
318320
let body = self.collect_labelled_block_opt(label, e.loop_body());
319321
let condition = self.collect_expr_opt(e.condition());
320-
321-
self.alloc_expr(Expr::While { condition, body, label }, syntax_ptr)
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)
322329
}
323330
ast::Expr::ForExpr(e) => self.collect_for_loop(syntax_ptr, e),
324331
ast::Expr::CallExpr(e) => {

crates/hir-ty/src/tests/macros.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ fn expr_macro_def_expanded_in_various_places() {
209209
104..105 '_': IntoIterator::Item<isize>
210210
117..119 '{}': ()
211211
124..134 '|| spam!()': impl Fn() -> isize
212+
140..156 'while ...!() {}': !
213+
140..156 'while ...!() {}': ()
212214
140..156 'while ...!() {}': ()
213215
154..156 '{}': ()
214216
161..174 'break spam!()': !
@@ -300,6 +302,8 @@ fn expr_macro_rules_expanded_in_various_places() {
300302
118..119 '_': IntoIterator::Item<isize>
301303
131..133 '{}': ()
302304
138..148 '|| spam!()': impl Fn() -> isize
305+
154..170 'while ...!() {}': !
306+
154..170 'while ...!() {}': ()
303307
154..170 'while ...!() {}': ()
304308
168..170 '{}': ()
305309
175..188 'break spam!()': !

crates/hir-ty/src/tests/never_type.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,17 +412,23 @@ fn diverging_expression_3_break() {
412412
355..654 '{ ...; }; }': ()
413413
398..399 'x': u32
414414
407..433 '{ whil...; }; }': u32
415+
409..430 'while ...eak; }': !
416+
409..430 'while ...eak; }': ()
415417
409..430 'while ...eak; }': ()
416418
415..419 'true': bool
417419
420..430 '{ break; }': ()
418420
422..427 'break': !
419421
537..538 'x': u32
420422
546..564 '{ whil... {}; }': u32
423+
548..561 'while true {}': !
424+
548..561 'while true {}': ()
421425
548..561 'while true {}': ()
422426
554..558 'true': bool
423427
559..561 '{}': ()
424428
615..616 'x': u32
425429
624..651 '{ whil...; }; }': u32
430+
626..648 'while ...urn; }': !
431+
626..648 'while ...urn; }': ()
426432
626..648 'while ...urn; }': ()
427433
632..636 'true': bool
428434
637..648 '{ return; }': ()

crates/hir-ty/src/tests/regression.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,8 @@ fn test() {
12671267
"#,
12681268
expect![[r#"
12691269
10..59 '{ ... } }': ()
1270+
16..57 'while ... }': !
1271+
16..57 'while ... }': ()
12701272
16..57 'while ... }': ()
12711273
22..30 '{ true }': bool
12721274
24..28 'true': bool

0 commit comments

Comments
 (0)