@@ -2503,9 +2503,27 @@ impl<'a> Parser<'a> {
2503
2503
let ( attrs, loop_block) = self . parse_inner_attrs_and_block ( ) ?;
2504
2504
2505
2505
let kind = ExprKind :: ForLoop ( pat, expr, loop_block, opt_label) ;
2506
+
2507
+ self . recover_loop_else ( "for" , lo) ?;
2508
+
2506
2509
Ok ( self . mk_expr_with_attrs ( lo. to ( self . prev_token . span ) , kind, attrs) )
2507
2510
}
2508
2511
2512
+ /// Recovers from an `else` clause after a loop (`for...else`, `while...else`)
2513
+ fn recover_loop_else ( & mut self , loop_kind : & ' static str , loop_kw : Span ) -> PResult < ' a , ( ) > {
2514
+ if self . token . is_keyword ( kw:: Else ) && self . may_recover ( ) {
2515
+ let else_span = self . token . span ;
2516
+ self . bump ( ) ;
2517
+ let else_clause = self . parse_expr_else ( ) ?;
2518
+ self . sess . emit_err ( errors:: LoopElseNotSupported {
2519
+ span : else_span. to ( else_clause. span ) ,
2520
+ loop_kind,
2521
+ loop_kw,
2522
+ } ) ;
2523
+ }
2524
+ Ok ( ( ) )
2525
+ }
2526
+
2509
2527
fn error_missing_in_for_loop ( & mut self ) {
2510
2528
let ( span, sub) : ( _ , fn ( _) -> _ ) = if self . token . is_ident_named ( sym:: of) {
2511
2529
// Possibly using JS syntax (#75311).
@@ -2530,6 +2548,9 @@ impl<'a> Parser<'a> {
2530
2548
err. span_label ( cond. span , "this `while` condition successfully parsed" ) ;
2531
2549
err
2532
2550
} ) ?;
2551
+
2552
+ self . recover_loop_else ( "while" , lo) ?;
2553
+
2533
2554
Ok ( self . mk_expr_with_attrs (
2534
2555
lo. to ( self . prev_token . span ) ,
2535
2556
ExprKind :: While ( cond, body, opt_label) ,
@@ -2541,6 +2562,7 @@ impl<'a> Parser<'a> {
2541
2562
fn parse_expr_loop ( & mut self , opt_label : Option < Label > , lo : Span ) -> PResult < ' a , P < Expr > > {
2542
2563
let loop_span = self . prev_token . span ;
2543
2564
let ( attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
2565
+ self . recover_loop_else ( "loop" , lo) ?;
2544
2566
Ok ( self . mk_expr_with_attrs (
2545
2567
lo. to ( self . prev_token . span ) ,
2546
2568
ExprKind :: Loop ( body, opt_label, loop_span) ,
0 commit comments