about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/stmt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src/parser/stmt.rs')
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs98
1 files changed, 89 insertions, 9 deletions
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index b7cdae3e3e1..e8877b8c541 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -475,6 +475,7 @@ impl<'a> Parser<'a> {
     }
 
     fn error_block_no_opening_brace_msg(&mut self, msg: Cow<'static, str>) -> Diag<'a> {
+        let prev = self.prev_token.span;
         let sp = self.token.span;
         let mut e = self.dcx().struct_span_err(sp, msg);
         let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
@@ -514,15 +515,94 @@ impl<'a> Parser<'a> {
                 } else {
                     stmt.span
                 };
-                e.multipart_suggestion(
-                    "try placing this code inside a block",
-                    vec![
-                        (stmt_span.shrink_to_lo(), "{ ".to_string()),
-                        (stmt_span.shrink_to_hi(), " }".to_string()),
-                    ],
-                    // Speculative; has been misleading in the past (#46836).
-                    Applicability::MaybeIncorrect,
-                );
+                match (&self.token.kind, &stmt.kind) {
+                    (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                        if let ExprKind::Call(..) = expr.kind =>
+                    {
+                        // for _ in x y() {}
+                        e.span_suggestion_verbose(
+                            prev.between(sp),
+                            "you might have meant to write a method call",
+                            ".".to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                        if let ExprKind::Field(..) = expr.kind =>
+                    {
+                        // for _ in x y.z {}
+                        e.span_suggestion_verbose(
+                            prev.between(sp),
+                            "you might have meant to write a field access",
+                            ".".to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    (token::CloseDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                        if let ExprKind::Struct(expr) = &expr.kind
+                            && let None = expr.qself
+                            && expr.path.segments.len() == 1 =>
+                    {
+                        // This is specific to "mistyped `if` condition followed by empty body"
+                        //
+                        // for _ in x y {}
+                        e.span_suggestion_verbose(
+                            prev.between(sp),
+                            "you might have meant to write a field access",
+                            ".".to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                        if let ExprKind::Lit(lit) = expr.kind
+                            && let None = lit.suffix
+                            && let token::LitKind::Integer | token::LitKind::Float = lit.kind =>
+                    {
+                        // for _ in x 0 {}
+                        // for _ in x 0.0 {}
+                        e.span_suggestion_verbose(
+                            prev.between(sp),
+                            format!("you might have meant to write a field access"),
+                            ".".to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    (token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
+                        if let ExprKind::Loop(..)
+                        | ExprKind::If(..)
+                        | ExprKind::While(..)
+                        | ExprKind::Match(..)
+                        | ExprKind::ForLoop { .. }
+                        | ExprKind::TryBlock(..)
+                        | ExprKind::Ret(..)
+                        | ExprKind::Closure(..)
+                        | ExprKind::Struct(..)
+                        | ExprKind::Try(..) = expr.kind =>
+                    {
+                        // These are more likely to have been meant as a block body.
+                        e.multipart_suggestion(
+                            "try placing this code inside a block",
+                            vec![
+                                (stmt_span.shrink_to_lo(), "{ ".to_string()),
+                                (stmt_span.shrink_to_hi(), " }".to_string()),
+                            ],
+                            // Speculative; has been misleading in the past (#46836).
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                    (token::OpenDelim(Delimiter::Brace), _) => {}
+                    (_, _) => {
+                        e.multipart_suggestion(
+                            "try placing this code inside a block",
+                            vec![
+                                (stmt_span.shrink_to_lo(), "{ ".to_string()),
+                                (stmt_span.shrink_to_hi(), " }".to_string()),
+                            ],
+                            // Speculative; has been misleading in the past (#46836).
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
             }
             Err(e) => {
                 self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);