diff options
Diffstat (limited to 'compiler/rustc_parse/src/parser/expr.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 24d4c17f5d8..b2951e7a184 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2503,9 +2503,27 @@ impl<'a> Parser<'a> { let (attrs, loop_block) = self.parse_inner_attrs_and_block()?; let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label); + + self.recover_loop_else("for", lo)?; + Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs)) } + /// Recovers from an `else` clause after a loop (`for...else`, `while...else`) + fn recover_loop_else(&mut self, loop_kind: &'static str, loop_kw: Span) -> PResult<'a, ()> { + if self.token.is_keyword(kw::Else) && self.may_recover() { + let else_span = self.token.span; + self.bump(); + let else_clause = self.parse_expr_else()?; + self.sess.emit_err(errors::LoopElseNotSupported { + span: else_span.to(else_clause.span), + loop_kind, + loop_kw, + }); + } + Ok(()) + } + fn error_missing_in_for_loop(&mut self) { let (span, sub): (_, fn(_) -> _) = if self.token.is_ident_named(sym::of) { // Possibly using JS syntax (#75311). @@ -2530,6 +2548,9 @@ impl<'a> Parser<'a> { err.span_label(cond.span, "this `while` condition successfully parsed"); err })?; + + self.recover_loop_else("while", lo)?; + Ok(self.mk_expr_with_attrs( lo.to(self.prev_token.span), ExprKind::While(cond, body, opt_label), @@ -2541,6 +2562,7 @@ impl<'a> Parser<'a> { fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { let loop_span = self.prev_token.span; let (attrs, body) = self.parse_inner_attrs_and_block()?; + self.recover_loop_else("loop", lo)?; Ok(self.mk_expr_with_attrs( lo.to(self.prev_token.span), ExprKind::Loop(body, opt_label, loop_span), |
