about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2023-05-03 11:46:34 +0800
committeryukang <moorekang@gmail.com>2023-05-08 10:56:20 +0800
commit0bb43c63c33bf29e7a24e696f619be8e55e62f37 (patch)
tree35e583a3194d2e531e3d49a8b9daf112ae813926
parentad6b20bf5225c65aab30169c9a173719f5bdfc04 (diff)
downloadrust-0bb43c63c33bf29e7a24e696f619be8e55e62f37.tar.gz
rust-0bb43c63c33bf29e7a24e696f619be8e55e62f37.zip
Suggest let for possible binding with ty
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs17
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs9
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.fixed11
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.rs4
-rw-r--r--tests/ui/suggestions/type-ascription-instead-of-let.stderr7
-rw-r--r--tests/ui/type/missing-let-in-binding-2.fixed5
-rw-r--r--tests/ui/type/missing-let-in-binding-2.rs5
-rw-r--r--tests/ui/type/missing-let-in-binding-2.stderr13
9 files changed, 61 insertions, 12 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index bd84681cbb4..a536eb3b04e 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -140,7 +140,7 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 /// ```fluent
 /// parser_expected_identifier = expected identifier
 ///
-/// parser_expected_identifier-found = expected identifier, found {$found}
+/// parser_expected_identifier_found = expected identifier, found {$found}
 ///
 /// parser_raw_identifier = escape `{$ident}` to use it as an identifier
 /// ```
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 36883bd2172..e8f47346fa7 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -399,6 +399,23 @@ 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();
+            let res = self.parse_ty();
+            if res.is_ok() && self.token == token::Eq {
+                err.span_suggestion_verbose(
+                    prev_span,
+                    "you might have meant to introduce a new binding",
+                    "let ".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            self.restore_snapshot(snapshot);
+        }
 
         if let Some(recovered_ident) = recovered_ident && recover {
             err.emit();
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 1c17de337e8..ab04219b177 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -555,7 +555,6 @@ impl<'a> Parser<'a> {
                     if self.token == token::Colon {
                         // if next token is following a colon, it's likely a path
                         // and we can suggest a path separator
-                        let ident_span = self.prev_token.span;
                         self.bump();
                         if self.token.span.lo() == self.prev_token.span.hi() {
                             err.span_suggestion_verbose(
@@ -565,14 +564,6 @@ impl<'a> Parser<'a> {
                                 Applicability::MaybeIncorrect,
                             );
                         }
-                        if self.look_ahead(1, |token| token == &token::Eq) {
-                            err.span_suggestion_verbose(
-                                ident_span.shrink_to_lo(),
-                                "you might have meant to introduce a new binding",
-                                "let ",
-                                Applicability::MaybeIncorrect,
-                            );
-                        }
                         if self.sess.unstable_features.is_nightly_build() {
                             // FIXME(Nilstrieb): Remove this again after a few months.
                             err.note("type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>");
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.fixed b/tests/ui/suggestions/type-ascription-instead-of-let.fixed
new file mode 100644
index 00000000000..e3d03b6f22a
--- /dev/null
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.fixed
@@ -0,0 +1,11 @@
+// run-rustfix
+
+fn fun(x: i32) -> i32 { x }
+
+fn main() {
+    let _closure_annotated = |value: i32| -> i32 {
+        let temp: i32 = fun(5i32);
+        //~^ ERROR expected identifier, found `:`
+        temp + value + 1
+    };
+}
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.rs b/tests/ui/suggestions/type-ascription-instead-of-let.rs
index 5ad60243298..6e1c86f9671 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-let.rs
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
 fn fun(x: i32) -> i32 { x }
 
 fn main() {
-    let closure_annotated = |value: i32| -> i32 {
+    let _closure_annotated = |value: i32| -> i32 {
         temp: i32 = fun(5i32);
         //~^ ERROR expected identifier, found `:`
         temp + value + 1
diff --git a/tests/ui/suggestions/type-ascription-instead-of-let.stderr b/tests/ui/suggestions/type-ascription-instead-of-let.stderr
index fb697b0ccfd..065b1f4d353 100644
--- a/tests/ui/suggestions/type-ascription-instead-of-let.stderr
+++ b/tests/ui/suggestions/type-ascription-instead-of-let.stderr
@@ -1,8 +1,13 @@
 error: expected identifier, found `:`
-  --> $DIR/type-ascription-instead-of-let.rs:5:13
+  --> $DIR/type-ascription-instead-of-let.rs:7:13
    |
 LL |         temp: i32 = fun(5i32);
    |             ^ expected identifier
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |         let temp: i32 = fun(5i32);
+   |         +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/type/missing-let-in-binding-2.fixed b/tests/ui/type/missing-let-in-binding-2.fixed
new file mode 100644
index 00000000000..d64013c8c83
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+    let _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:`
+}
diff --git a/tests/ui/type/missing-let-in-binding-2.rs b/tests/ui/type/missing-let-in-binding-2.rs
new file mode 100644
index 00000000000..f95f7bef215
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.rs
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+    _v: Vec<i32> = vec![1, 2, 3]; //~ ERROR expected identifier, found `:`
+}
diff --git a/tests/ui/type/missing-let-in-binding-2.stderr b/tests/ui/type/missing-let-in-binding-2.stderr
new file mode 100644
index 00000000000..2e10125943e
--- /dev/null
+++ b/tests/ui/type/missing-let-in-binding-2.stderr
@@ -0,0 +1,13 @@
+error: expected identifier, found `:`
+  --> $DIR/missing-let-in-binding-2.rs:4:7
+   |
+LL |     _v: Vec<i32> = vec![1, 2, 3];
+   |       ^ expected identifier
+   |
+help: you might have meant to introduce a new binding
+   |
+LL |     let _v: Vec<i32> = vec![1, 2, 3];
+   |     +++
+
+error: aborting due to previous error
+