]> git.lizzy.rs Git - rust.git/commitdiff
Recover from missing expression in for loop
authorObei Sideg <obei.sideg@gmail.com>
Fri, 3 Feb 2023 09:23:37 +0000 (12:23 +0300)
committerObei Sideg <obei.sideg@gmail.com>
Sun, 5 Feb 2023 14:33:10 +0000 (17:33 +0300)
compiler/rustc_error_messages/locales/en-US/parse.ftl
compiler/rustc_parse/src/errors.rs
compiler/rustc_parse/src/parser/expr.rs

index 244eb41eb39eba2ba32b4d0556d939293df4fc51..2ef3dba557ea5f32ca4891395c56aea0a7237b64 100644 (file)
@@ -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
 
index fd4333dbbecc3763f3dace3162c65890403af1cc..fc7c839f1c461f4033e4aee2c43b85b1ef96bde1 100644 (file)
@@ -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 {
index 473a5bb8cb8c15fddf8ade2fcd4943f1cdbe495b..c37808f8c3d19b244e01abe806ef5f50e59ccba9 100644 (file)
@@ -2471,6 +2471,21 @@ fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'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);