recover from for-else and while-else
This commit is contained in:
parent
64165aac68
commit
0758c05c97
20 changed files with 218 additions and 22 deletions
|
@ -451,6 +451,17 @@ pub(crate) struct MissingExpressionInForLoop {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_loop_else)]
|
||||
#[note]
|
||||
pub(crate) struct LoopElseNotSupported {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub loop_kind: &'static str,
|
||||
#[label(parse_loop_keyword)]
|
||||
pub loop_kw: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_missing_comma_after_match_arm)]
|
||||
pub(crate) struct MissingCommaAfterMatchArm {
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue