about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2023-05-08 14:52:52 +0800
committeryukang <moorekang@gmail.com>2023-05-08 14:56:36 +0800
commit5e94b5faf1f0812207a9128e2754bd146210b16e (patch)
treef7b2a4d14e68bef64b72c1845ebd888f01910cce
parenta7fc32ceaf4708a26a992f61c4ac4ead1555c8eb (diff)
downloadrust-5e94b5faf1f0812207a9128e2754bd146210b16e.tar.gz
rust-5e94b5faf1f0812207a9128e2754bd146210b16e.zip
code refactor and fix wrong suggestion
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs52
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs8
-rw-r--r--tests/ui/type/missing-let-in-binding-4.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-4.stderr10
4 files changed, 51 insertions, 24 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 456c6243bbb..b0822fe7956 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -399,29 +399,6 @@ impl<'a> Parser<'a> {
                 }
             }
         }
-        // we suggest add the missing `let` before the identifier
-        // `a: Ty = 1` -> `let a: Ty = 1`
-        if self.token == token::Colon {
-            let prev_span = self.prev_token.span.shrink_to_lo();
-            let snapshot = self.create_snapshot_for_diagnostic();
-            self.bump();
-            match self.parse_ty() {
-                Ok(_) => {
-                    if self.token == token::Eq {
-                        err.span_suggestion_verbose(
-                            prev_span,
-                            "you might have meant to introduce a new binding",
-                            "let ".to_string(),
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                }
-                Err(err) => {
-                    err.cancel();
-                }
-            }
-            self.restore_snapshot(snapshot);
-        }
 
         if let Some(recovered_ident) = recovered_ident && recover {
             err.emit();
@@ -1029,6 +1006,35 @@ impl<'a> Parser<'a> {
         Err(e)
     }
 
+    /// Suggest add the missing `let` before the identifier in stmt
+    /// `a: Ty = 1` -> `let a: Ty = 1`
+    pub(super) fn suggest_add_missing_let_for_stmt(
+        &mut self,
+        err: &mut DiagnosticBuilder<'a, ErrorGuaranteed>,
+    ) {
+        if self.token == token::Colon {
+            let prev_span = self.prev_token.span.shrink_to_lo();
+            let snapshot = self.create_snapshot_for_diagnostic();
+            self.bump();
+            match self.parse_ty() {
+                Ok(_) => {
+                    if self.token == token::Eq {
+                        err.span_suggestion_verbose(
+                            prev_span,
+                            "you might have meant to introduce a new binding",
+                            "let ".to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
+                Err(e) => {
+                    e.cancel();
+                }
+            }
+            self.restore_snapshot(snapshot);
+        }
+    }
+
     /// Check to see if a pair of chained operators looks like an attempt at chained comparison,
     /// e.g. `1 < x <= 3`. If so, suggest either splitting the comparison into two, or
     /// parenthesising the leftmost comparison.
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ab04219b177..c35c32f272a 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -99,7 +99,13 @@ impl<'a> Parser<'a> {
                 ForceCollect::Yes => {
                     self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs))?
                 }
-                ForceCollect::No => self.parse_stmt_path_start(lo, attrs)?,
+                ForceCollect::No => match self.parse_stmt_path_start(lo, attrs) {
+                    Ok(stmt) => stmt,
+                    Err(mut err) => {
+                        self.suggest_add_missing_let_for_stmt(&mut err);
+                        return Err(err);
+                    }
+                },
             }
         } else if let Some(item) = self.parse_item_common(
             attrs.clone(),
diff --git a/tests/ui/type/missing-let-in-binding-4.rs b/tests/ui/type/missing-let-in-binding-4.rs
new file mode 100644
index 00000000000..879a6fedcd6
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-4.rs
@@ -0,0 +1,5 @@
+struct A {
+    : u8 =, //~ ERROR expected identifier, found `:`
+}
+
+fn main() {}
diff --git a/tests/ui/type/missing-let-in-binding-4.stderr b/tests/ui/type/missing-let-in-binding-4.stderr
new file mode 100644
index 00000000000..e6f173a6658
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-4.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `:`
+  --> $DIR/missing-let-in-binding-4.rs:2:5
+   |
+LL | struct A {
+   |        - while parsing this struct
+LL |     : u8 =,
+   |     ^ expected identifier
+
+error: aborting due to previous error
+