@@ -313,13 +313,7 @@ impl ExprCollector<'_> {
313
313
let body = self . collect_labelled_block_opt ( label, e. loop_body ( ) ) ;
314
314
self . alloc_expr ( Expr :: Loop { body, label } , syntax_ptr)
315
315
}
316
- ast:: Expr :: WhileExpr ( e) => {
317
- let label = e. label ( ) . map ( |label| self . collect_label ( label) ) ;
318
- let body = self . collect_labelled_block_opt ( label, e. loop_body ( ) ) ;
319
- let condition = self . collect_expr_opt ( e. condition ( ) ) ;
320
-
321
- self . alloc_expr ( Expr :: While { condition, body, label } , syntax_ptr)
322
- }
316
+ ast:: Expr :: WhileExpr ( e) => self . collect_while_loop ( syntax_ptr, e) ,
323
317
ast:: Expr :: ForExpr ( e) => self . collect_for_loop ( syntax_ptr, e) ,
324
318
ast:: Expr :: CallExpr ( e) => {
325
319
let is_rustc_box = {
@@ -731,6 +725,32 @@ impl ExprCollector<'_> {
731
725
expr_id
732
726
}
733
727
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
+
734
754
/// Desugar `ast::ForExpr` from: `[opt_ident]: for <pat> in <head> <body>` into:
735
755
/// ```ignore (pseudo-rust)
736
756
/// match IntoIterator::into_iter(<head>) {
@@ -893,15 +913,14 @@ impl ExprCollector<'_> {
893
913
self . alloc_expr ( Expr :: Match { expr, arms } , syntax_ptr)
894
914
}
895
915
896
- fn collect_macro_call < F , T , U > (
916
+ fn collect_macro_call < T , U > (
897
917
& mut self ,
898
918
mcall : ast:: MacroCall ,
899
919
syntax_ptr : AstPtr < ast:: MacroCall > ,
900
920
record_diagnostics : bool ,
901
- collector : F ,
921
+ collector : impl FnOnce ( & mut Self , Option < T > ) -> U ,
902
922
) -> U
903
923
where
904
- F : FnOnce ( & mut Self , Option < T > ) -> U ,
905
924
T : ast:: AstNode ,
906
925
{
907
926
// File containing the macro call. Expansion errors will be attached here.
0 commit comments