about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-05-09 12:33:46 +0530
committerGitHub <noreply@github.com>2023-05-09 12:33:46 +0530
commit8c51701b8a5ac3a2fbfbad9f6d386ec443344293 (patch)
tree279439a8af041610464a269c0f0c2c7558db4879 /compiler/rustc_parse/src/parser
parentdbd090c655b4a4389fe51cbd3ad6f401e2953dbe (diff)
parent4d219d066626c49fdec3d8fa143a94c81150b633 (diff)
downloadrust-8c51701b8a5ac3a2fbfbad9f6d386ec443344293.tar.gz
rust-8c51701b8a5ac3a2fbfbad9f6d386ec443344293.zip
Rollup merge of #111120 - chenyukang:yukang-suggest-let, r=Nilstrieb
Suggest let for possible binding with ty

Origin from https://github.com/rust-lang/rust/pull/109128#discussion_r1179866137

r? `@Nilstrieb`
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs31
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs17
2 files changed, 35 insertions, 13 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 36883bd2172..3002f23da75 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -13,7 +13,7 @@ use crate::errors::{
     IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg,
     PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
     StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens,
-    StructLiteralNeedingParensSugg, SuggEscapeIdentifier, SuggRemoveComma,
+    StructLiteralNeedingParensSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma,
     UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
     UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead,
 };
@@ -32,8 +32,8 @@ use rustc_ast::{
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
-    pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed,
-    FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
+    pluralize, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
+    ErrorGuaranteed, FatalError, Handler, IntoDiagnostic, MultiSpan, PResult,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
@@ -1006,6 +1006,31 @@ 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 {
+                        let sugg = SuggAddMissingLetStmt { span: prev_span };
+                        sugg.add_to_diagnostic(err);
+                    }
+                }
+                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 a0bd086053e..03279124177 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -103,7 +103,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(),
@@ -559,7 +565,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(
@@ -569,14 +574,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>");