hir: Desugar while to loop and break

This commit is contained in:
Tadeo Kondrak 2023-08-01 19:04:36 -06:00
parent 151c750dac
commit 31bcba84f9
4 changed files with 21 additions and 2 deletions

View file

@ -314,11 +314,18 @@ impl ExprCollector<'_> {
self.alloc_expr(Expr::Loop { body, label }, syntax_ptr)
}
ast::Expr::WhileExpr(e) => {
// Desugar `while <cond> { <body> }` to
// `loop { if <cond> { <body> } else { break } }`
let label = e.label().map(|label| self.collect_label(label));
let body = self.collect_labelled_block_opt(label, e.loop_body());
let condition = self.collect_expr_opt(e.condition());
self.alloc_expr(Expr::While { condition, body, label }, syntax_ptr)
let break_expr =
self.alloc_expr(Expr::Break { expr: None, label: None }, syntax_ptr.clone());
let if_expr = self.alloc_expr(
Expr::If { condition, then_branch: body, else_branch: Some(break_expr) },
syntax_ptr.clone(),
);
self.alloc_expr(Expr::Loop { body: if_expr, label }, syntax_ptr)
}
ast::Expr::ForExpr(e) => self.collect_for_loop(syntax_ptr, e),
ast::Expr::CallExpr(e) => {

View file

@ -209,6 +209,8 @@ fn expr_macro_def_expanded_in_various_places() {
104..105 '_': IntoIterator::Item<isize>
117..119 '{}': ()
124..134 '|| spam!()': impl Fn() -> isize
140..156 'while ...!() {}': !
140..156 'while ...!() {}': ()
140..156 'while ...!() {}': ()
154..156 '{}': ()
161..174 'break spam!()': !
@ -300,6 +302,8 @@ fn expr_macro_rules_expanded_in_various_places() {
118..119 '_': IntoIterator::Item<isize>
131..133 '{}': ()
138..148 '|| spam!()': impl Fn() -> isize
154..170 'while ...!() {}': !
154..170 'while ...!() {}': ()
154..170 'while ...!() {}': ()
168..170 '{}': ()
175..188 'break spam!()': !

View file

@ -412,17 +412,23 @@ fn diverging_expression_3_break() {
355..654 '{ ...; }; }': ()
398..399 'x': u32
407..433 '{ whil...; }; }': u32
409..430 'while ...eak; }': !
409..430 'while ...eak; }': ()
409..430 'while ...eak; }': ()
415..419 'true': bool
420..430 '{ break; }': ()
422..427 'break': !
537..538 'x': u32
546..564 '{ whil... {}; }': u32
548..561 'while true {}': !
548..561 'while true {}': ()
548..561 'while true {}': ()
554..558 'true': bool
559..561 '{}': ()
615..616 'x': u32
624..651 '{ whil...; }; }': u32
626..648 'while ...urn; }': !
626..648 'while ...urn; }': ()
626..648 'while ...urn; }': ()
632..636 'true': bool
637..648 '{ return; }': ()

View file

@ -1267,6 +1267,8 @@ fn test() {
"#,
expect![[r#"
10..59 '{ ... } }': ()
16..57 'while ... }': !
16..57 'while ... }': ()
16..57 'while ... }': ()
22..30 '{ true }': bool
24..28 'true': bool