@@ -2491,9 +2491,26 @@ impl<'a> Parser<'a> {
24912491 let ( attrs, loop_block) = self . parse_inner_attrs_and_block ( ) ?;
24922492
24932493 let kind = ExprKind :: ForLoop ( pat, expr, loop_block, opt_label) ;
2494+
2495+ self . recover_loop_else ( "for" ) ?;
2496+
24942497 Ok ( self . mk_expr_with_attrs ( lo. to ( self . prev_token . span ) , kind, attrs) )
24952498 }
24962499
2500+ /// Recovers from an `else` clause after a loop (`for...else`, `while...else`)
2501+ fn recover_loop_else ( & mut self , loop_kind : & ' static str ) -> PResult < ' a , ( ) > {
2502+ if self . token . is_keyword ( kw:: Else ) && self . may_recover ( ) {
2503+ let else_span = self . token . span ;
2504+ self . bump ( ) ;
2505+ let else_clause = self . parse_else_expr ( ) ?;
2506+ self . sess . emit_err ( errors:: LoopElseNotSupported {
2507+ span : else_span. to ( else_clause. span ) ,
2508+ loop_kind,
2509+ } ) ;
2510+ }
2511+ Ok ( ( ) )
2512+ }
2513+
24972514 fn error_missing_in_for_loop ( & mut self ) {
24982515 let ( span, sub) : ( _ , fn ( _) -> _ ) = if self . token . is_ident_named ( sym:: of) {
24992516 // Possibly using JS syntax (#75311).
@@ -2518,6 +2535,9 @@ impl<'a> Parser<'a> {
25182535 err. span_label ( cond. span , "this `while` condition successfully parsed" ) ;
25192536 err
25202537 } ) ?;
2538+
2539+ self . recover_loop_else ( "while" ) ?;
2540+
25212541 Ok ( self . mk_expr_with_attrs (
25222542 lo. to ( self . prev_token . span ) ,
25232543 ExprKind :: While ( cond, body, opt_label) ,
0 commit comments