Skip to content

Commit

Permalink
Auto merge of #107526 - obeis:for-missing-iterator, r=estebank,compil…
Browse files Browse the repository at this point in the history
…er-errors

Recover form missing expression in `for` loop

Close #78537
r? `@estebank`
  • Loading branch information
bors committed Feb 5, 2023
2 parents a676496 + 17b6bd6 commit 75a0be9
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 0 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/parse.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ parse_missing_in_in_for_loop = missing `in` in `for` loop
.use_in_not_of = try using `in` here instead
.add_in = try adding `in` here
parse_missing_expression_in_for_loop = missing expression to iterate on in `for` loop
.suggestion = try adding an expression to the `for` loop
parse_missing_comma_after_match_arm = expected `,` following `match` arm
.suggestion = missing a comma here to end this `match` arm
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,18 @@ pub(crate) enum MissingInInForLoopSub {
AddIn(#[primary_span] Span),
}

#[derive(Diagnostic)]
#[diag(parse_missing_expression_in_for_loop)]
pub(crate) struct MissingExpressionInForLoop {
#[primary_span]
#[suggestion(
code = "/* expression */ ",
applicability = "has-placeholders",
style = "verbose"
)]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_missing_comma_after_match_arm)]
pub(crate) struct MissingCommaAfterMatchArm {
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2471,6 +2471,21 @@ impl<'a> Parser<'a> {

let pat = self.recover_parens_around_for_head(pat, begin_paren);

// Recover from missing expression in `for` loop
if matches!(expr.kind, ExprKind::Block(..))
&& !matches!(self.token.kind, token::OpenDelim(token::Delimiter::Brace))
&& self.may_recover()
{
self.sess
.emit_err(errors::MissingExpressionInForLoop { span: expr.span.shrink_to_lo() });
let err_expr = self.mk_expr(expr.span, ExprKind::Err);
let block = self.mk_block(vec![], BlockCheckMode::Default, self.prev_token.span);
return Ok(self.mk_expr(
lo.to(self.prev_token.span),
ExprKind::ForLoop(pat, err_expr, block, opt_label),
));
}

let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;

let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label);
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/parser/missing-expression-in-for-loop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() {
for i in {
//~^ ERROR missing expression to iterate on in `for` loop
}
}
13 changes: 13 additions & 0 deletions tests/ui/parser/missing-expression-in-for-loop.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: missing expression to iterate on in `for` loop
--> $DIR/missing-expression-in-for-loop.rs:2:14
|
LL | for i in {
| ^
|
help: try adding an expression to the `for` loop
|
LL | for i in /* expression */ {
| ++++++++++++++++

error: aborting due to previous error

0 comments on commit 75a0be9

Please sign in to comment.