Skip to content

Commit 75a0be9

Browse files
committed
Auto merge of #107526 - obeis:for-missing-iterator, r=estebank,compiler-errors
Recover form missing expression in `for` loop Close #78537 r? `@estebank`
2 parents a676496 + 17b6bd6 commit 75a0be9

File tree

5 files changed

+48
-0
lines changed

5 files changed

+48
-0
lines changed

compiler/rustc_error_messages/locales/en-US/parse.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ parse_missing_in_in_for_loop = missing `in` in `for` loop
128128
.use_in_not_of = try using `in` here instead
129129
.add_in = try adding `in` here
130130
131+
parse_missing_expression_in_for_loop = missing expression to iterate on in `for` loop
132+
.suggestion = try adding an expression to the `for` loop
133+
131134
parse_missing_comma_after_match_arm = expected `,` following `match` arm
132135
.suggestion = missing a comma here to end this `match` arm
133136

compiler/rustc_parse/src/errors.rs

+12
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,18 @@ pub(crate) enum MissingInInForLoopSub {
433433
AddIn(#[primary_span] Span),
434434
}
435435

436+
#[derive(Diagnostic)]
437+
#[diag(parse_missing_expression_in_for_loop)]
438+
pub(crate) struct MissingExpressionInForLoop {
439+
#[primary_span]
440+
#[suggestion(
441+
code = "/* expression */ ",
442+
applicability = "has-placeholders",
443+
style = "verbose"
444+
)]
445+
pub span: Span,
446+
}
447+
436448
#[derive(Diagnostic)]
437449
#[diag(parse_missing_comma_after_match_arm)]
438450
pub(crate) struct MissingCommaAfterMatchArm {

compiler/rustc_parse/src/parser/expr.rs

+15
Original file line numberDiff line numberDiff line change
@@ -2471,6 +2471,21 @@ impl<'a> Parser<'a> {
24712471

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

2474+
// Recover from missing expression in `for` loop
2475+
if matches!(expr.kind, ExprKind::Block(..))
2476+
&& !matches!(self.token.kind, token::OpenDelim(token::Delimiter::Brace))
2477+
&& self.may_recover()
2478+
{
2479+
self.sess
2480+
.emit_err(errors::MissingExpressionInForLoop { span: expr.span.shrink_to_lo() });
2481+
let err_expr = self.mk_expr(expr.span, ExprKind::Err);
2482+
let block = self.mk_block(vec![], BlockCheckMode::Default, self.prev_token.span);
2483+
return Ok(self.mk_expr(
2484+
lo.to(self.prev_token.span),
2485+
ExprKind::ForLoop(pat, err_expr, block, opt_label),
2486+
));
2487+
}
2488+
24742489
let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
24752490

24762491
let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
for i in {
3+
//~^ ERROR missing expression to iterate on in `for` loop
4+
}
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: missing expression to iterate on in `for` loop
2+
--> $DIR/missing-expression-in-for-loop.rs:2:14
3+
|
4+
LL | for i in {
5+
| ^
6+
|
7+
help: try adding an expression to the `for` loop
8+
|
9+
LL | for i in /* expression */ {
10+
| ++++++++++++++++
11+
12+
error: aborting due to previous error
13+

0 commit comments

Comments
 (0)