diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 6b4e2d0f4e2f5..fddbf5896ad83 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 "); + "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 "); 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 235e621d8827b..6ac7fe8f0921b 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 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 0000000000000..c63b09bb7a7f7 --- /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 0000000000000..4b00d1a24f317 --- /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 + +error: aborting due to 1 previous error +