@@ -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