From 863488dfd55c47ace05cc16ef9453831ca4335d5 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 7 Aug 2022 17:17:27 +0800 Subject: [PATCH] parser will not give wrong help message for 'public' --- compiler/rustc_ast/src/token.rs | 20 +++++++++++++++++++ .../rustc_parse/src/parser/diagnostics.rs | 18 ++++++++--------- compiler/rustc_span/src/symbol.rs | 1 + .../ui/parser/public-instead-of-pub-1.fixed | 11 ++++++++++ src/test/ui/parser/public-instead-of-pub-1.rs | 11 ++++++++++ .../ui/parser/public-instead-of-pub-1.stderr | 13 ++++++++++++ src/test/ui/parser/public-instead-of-pub-2.rs | 7 +++++++ .../ui/parser/public-instead-of-pub-2.stderr | 8 ++++++++ 8 files changed, 79 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/parser/public-instead-of-pub-1.fixed create mode 100644 src/test/ui/parser/public-instead-of-pub-1.rs create mode 100644 src/test/ui/parser/public-instead-of-pub-1.stderr create mode 100644 src/test/ui/parser/public-instead-of-pub-2.rs create mode 100644 src/test/ui/parser/public-instead-of-pub-2.stderr diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 85d9687c600dc..bd4ad2873c07c 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -436,6 +436,26 @@ impl Token { || self == &OpenDelim(Delimiter::Parenthesis) } + /// Returns `true` if the token can appear at the start of a item + pub fn can_begin_item(&self) -> bool { + self.is_keyword(kw::Use) + || self.is_keyword(kw::Fn) + || self.is_keyword(kw::Extern) + || self.is_keyword(kw::Crate) + || self.is_keyword(kw::Mod) + || self.is_keyword(kw::Const) + || self.is_keyword(kw::Static) + || self.is_keyword(kw::Trait) + || self.is_keyword(kw::Impl) + || self.is_keyword(kw::Mod) + || self.is_keyword(kw::Type) + || self.is_keyword(kw::Enum) + || self.is_keyword(kw::Struct) + || self.is_keyword(kw::Union) + || self.is_keyword(kw::Macro) + || self == &OpenDelim(Delimiter::Parenthesis) + } + /// Returns `true` if the token is any literal. pub fn is_lit(&self) -> bool { matches!(self.kind, Literal(..)) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a2155ac1d1ad4..1a3db94c93857 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -22,7 +22,7 @@ use rustc_errors::{ use rustc_errors::{pluralize, struct_span_err, Diagnostic, EmissionGuarantee, ErrorGuaranteed}; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; use rustc_span::source_map::Spanned; -use rustc_span::symbol::{kw, Ident}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, SpanSnippetError, DUMMY_SP}; use std::ops::{Deref, DerefMut}; @@ -602,15 +602,13 @@ impl<'a> Parser<'a> { self.last_unexpected_token_span = Some(self.token.span); let mut err = self.struct_span_err(self.token.span, &msg_exp); - if let TokenKind::Ident(symbol, _) = &self.prev_token.kind { - if symbol.as_str() == "public" { - err.span_suggestion_short( - self.prev_token.span, - "write `pub` instead of `public` to make the item public", - "pub", - appl, - ); - } + if self.prev_token.is_ident_named(sym::public) && self.token.can_begin_item() { + err.span_suggestion_short( + self.prev_token.span, + "write `pub` instead of `public` to make the item public", + "pub", + appl, + ); } // Add suggestion for a missing closing angle bracket if '>' is included in expected_tokens diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 791160ff6944e..16d3766d88e67 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1118,6 +1118,7 @@ symbols! { ptr_offset_from_unsigned, pub_macro_rules, pub_restricted, + public, pure, pushpop_unsafe, qreg, diff --git a/src/test/ui/parser/public-instead-of-pub-1.fixed b/src/test/ui/parser/public-instead-of-pub-1.fixed new file mode 100644 index 0000000000000..a4fa68ba5cc2f --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-1.fixed @@ -0,0 +1,11 @@ +// Checks what happens when `public` is used instead of the correct, `pub` +// run-rustfix + +pub enum Test { + //~^ ERROR expected one of `!` or `::`, found keyword `enum` + //~^^ HELP write `pub` instead of `public` to make the item public + A, + B, +} + +fn main() { } diff --git a/src/test/ui/parser/public-instead-of-pub-1.rs b/src/test/ui/parser/public-instead-of-pub-1.rs new file mode 100644 index 0000000000000..43565c9b1d25f --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-1.rs @@ -0,0 +1,11 @@ +// Checks what happens when `public` is used instead of the correct, `pub` +// run-rustfix + +public enum Test { + //~^ ERROR expected one of `!` or `::`, found keyword `enum` + //~^^ HELP write `pub` instead of `public` to make the item public + A, + B, +} + +fn main() { } diff --git a/src/test/ui/parser/public-instead-of-pub-1.stderr b/src/test/ui/parser/public-instead-of-pub-1.stderr new file mode 100644 index 0000000000000..795a5bcf5dfa6 --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-1.stderr @@ -0,0 +1,13 @@ +error: expected one of `!` or `::`, found keyword `enum` + --> $DIR/public-instead-of-pub-1.rs:4:8 + | +LL | public enum Test { + | ^^^^ expected one of `!` or `::` + | +help: write `pub` instead of `public` to make the item public + | +LL | pub enum Test { + | ~~~ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/public-instead-of-pub-2.rs b/src/test/ui/parser/public-instead-of-pub-2.rs new file mode 100644 index 0000000000000..8a43c361e0510 --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-2.rs @@ -0,0 +1,7 @@ +// Checks what happens when `public` is used instead of the correct, `pub` +// Won't give help message for this case + +public let x = 1; +//~^ ERROR expected one of `!` or `::`, found keyword `let` + +fn main() { } diff --git a/src/test/ui/parser/public-instead-of-pub-2.stderr b/src/test/ui/parser/public-instead-of-pub-2.stderr new file mode 100644 index 0000000000000..efe225656fd7f --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-2.stderr @@ -0,0 +1,8 @@ +error: expected one of `!` or `::`, found keyword `let` + --> $DIR/public-instead-of-pub-2.rs:4:8 + | +LL | public let x = 1; + | ^^^ expected one of `!` or `::` + +error: aborting due to previous error +