]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #107627 - nnethercote:optimize-fold_ty, r=compiler-errors
authorbors <bors@rust-lang.org>
Sun, 5 Feb 2023 23:13:41 +0000 (23:13 +0000)
committerbors <bors@rust-lang.org>
Sun, 5 Feb 2023 23:13:41 +0000 (23:13 +0000)
Optimize `fold_ty`

Micro-optimizing the heck out of the important `fold_ty` methods.

r? `@oli-obk`

compiler/rustc_error_messages/locales/en-US/parse.ftl
compiler/rustc_parse/src/errors.rs
compiler/rustc_parse/src/parser/expr.rs
tests/ui/parser/missing-expression-in-for-loop.rs [new file with mode: 0644]
tests/ui/parser/missing-expression-in-for-loop.stderr [new file with mode: 0644]

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);
diff --git a/tests/ui/parser/missing-expression-in-for-loop.rs b/tests/ui/parser/missing-expression-in-for-loop.rs
new file mode 100644 (file)
index 0000000..518a89a
--- /dev/null
@@ -0,0 +1,5 @@
+fn main() {
+    for i in {
+        //~^ ERROR missing expression to iterate on in `for` loop
+    }
+}
diff --git a/tests/ui/parser/missing-expression-in-for-loop.stderr b/tests/ui/parser/missing-expression-in-for-loop.stderr
new file mode 100644 (file)
index 0000000..74a7c42
--- /dev/null
@@ -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
+