diff options
| author | Jacob Pratt <jacob@jhpratt.dev> | 2024-11-17 22:30:51 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-17 22:30:51 -0500 |
| commit | 6c4a7b6ff3dab45dfb07f8a7c4730255223e87eb (patch) | |
| tree | ab4ae80e529e6f89472348487a5224e9dfc43dbb /compiler/rustc_parse/src/parser | |
| parent | 8600e579d58d2d5c23e423782c311f2193723543 (diff) | |
| parent | 7765f23ea14d16fb0182b475a0ec96891058ae24 (diff) | |
| download | rust-6c4a7b6ff3dab45dfb07f8a7c4730255223e87eb.tar.gz rust-6c4a7b6ff3dab45dfb07f8a7c4730255223e87eb.zip | |
Rollup merge of #133143 - kornelski:let-mut-global, r=compiler-errors
Diagnostics for let mut in item context The diagnostics for `let` at the top level did not account for `let mut`, which [made the error unclear](https://users.rust-lang.org/t/create-a-vector-of-constants-outside-main/121251/1). I've made the diagnostic always display a link to valid items. I've added dedicated help for `let mut` case that suggests using a `Mutex` (to steer novice users away from the `static mut` trap). Unfortunately, neither the Rust book, nor libstd docs have dedicated section listing all other types for interior-mutable `static`s.
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 33 |
1 files changed, 25 insertions, 8 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); } } |
