about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKornel <kornel@geekhood.net>2024-11-17 21:43:55 +0000
committerKornel <kornel@geekhood.net>2024-11-17 22:30:11 +0000
commit7765f23ea14d16fb0182b475a0ec96891058ae24 (patch)
tree3b89649d6c2d8a03c6d5f0c0734c7a8d31b16f3d
parenta8e75c53d0036b5d012cbc0ee5de17f8991fe60c (diff)
downloadrust-7765f23ea14d16fb0182b475a0ec96891058ae24.tar.gz
rust-7765f23ea14d16fb0182b475a0ec96891058ae24.zip
Diagnostics for let mut in item context
-rw-r--r--compiler/rustc_parse/src/parser/item.rs33
-rw-r--r--tests/ui/parser/suggest-const-for-global-var.stderr7
-rw-r--r--tests/ui/parser/suggest-static-for-global-var-mut.rs5
-rw-r--r--tests/ui/parser/suggest-static-for-global-var-mut.stderr11
4 files changed, 47 insertions, 9 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 6b4e2d0f4e2..fddbf5896ad 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -77,18 +77,35 @@ impl<'a> Parser<'a> {
         if !self.eat(term) {
             let token_str = super::token_descr(&self.token);
             if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {
+                let is_let = self.token.is_keyword(kw::Let);
+                let is_let_mut = is_let && self.look_ahead(1, |t| t.is_keyword(kw::Mut));
+                let let_has_ident = is_let && !is_let_mut && self.is_kw_followed_by_ident(kw::Let);
+
                 let msg = format!("expected item, found {token_str}");
                 let mut err = self.dcx().struct_span_err(self.token.span, msg);
-                let span = self.token.span;
-                if self.is_kw_followed_by_ident(kw::Let) {
-                    err.span_label(
-                        span,
-                        "consider using `const` or `static` instead of `let` for global variables",
-                    );
+
+                let label = if is_let {
+                    "`let` cannot be used for global variables"
                 } else {
-                    err.span_label(span, "expected item")
-                        .note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
+                    "expected item"
                 };
+                err.span_label(self.token.span, label);
+
+                if is_let {
+                    if is_let_mut {
+                        err.help("consider using `static` and a `Mutex` instead of `let mut`");
+                    } else if let_has_ident {
+                        err.span_suggestion_short(
+                            self.token.span,
+                            "consider using `static` or `const` instead of `let`",
+                            "static",
+                            Applicability::MaybeIncorrect,
+                        );
+                    } else {
+                        err.help("consider using `static` or `const` instead of `let`");
+                    }
+                }
+                err.note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
                 return Err(err);
             }
         }
diff --git a/tests/ui/parser/suggest-const-for-global-var.stderr b/tests/ui/parser/suggest-const-for-global-var.stderr
index 235e621d882..6ac7fe8f092 100644
--- a/tests/ui/parser/suggest-const-for-global-var.stderr
+++ b/tests/ui/parser/suggest-const-for-global-var.stderr
@@ -2,7 +2,12 @@ error: expected item, found keyword `let`
   --> $DIR/suggest-const-for-global-var.rs:1:1
    |
 LL | let X: i32 = 12;
-   | ^^^ consider using `const` or `static` instead of `let` for global variables
+   | ^^^
+   | |
+   | `let` cannot be used for global variables
+   | help: consider using `static` or `const` instead of `let`
+   |
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/suggest-static-for-global-var-mut.rs b/tests/ui/parser/suggest-static-for-global-var-mut.rs
new file mode 100644
index 00000000000..c63b09bb7a7
--- /dev/null
+++ b/tests/ui/parser/suggest-static-for-global-var-mut.rs
@@ -0,0 +1,5 @@
+let mut _data = vec![1,2,3];
+//~^ ERROR expected item, found keyword `let`
+
+fn main() {
+}
diff --git a/tests/ui/parser/suggest-static-for-global-var-mut.stderr b/tests/ui/parser/suggest-static-for-global-var-mut.stderr
new file mode 100644
index 00000000000..4b00d1a24f3
--- /dev/null
+++ b/tests/ui/parser/suggest-static-for-global-var-mut.stderr
@@ -0,0 +1,11 @@
+error: expected item, found keyword `let`
+  --> $DIR/suggest-static-for-global-var-mut.rs:1:1
+   |
+LL | let mut _data = vec![1,2,3];
+   | ^^^ `let` cannot be used for global variables
+   |
+   = help: consider using `static` and a `Mutex` instead of `let mut`
+   = note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
+
+error: aborting due to 1 previous error
+