Skip to content

Commit 1564318

Browse files
committed
Only have one source of truth for keywords.
`rustc_symbol` is the source of truth for keywords. rustdoc has its own implicit definition of keywords, via the `is_doc_keyword`. It (presumably) intends to include all keywords, but it omits `yeet`. rustfmt has its own explicit list of Rust keywords. It also (presumably) intends to include all keywords, but it omits `await`, `builtin`, `gen`, `macro_rules`, `raw`, `reuse`, `safe`, and `yeet`. Also, it does linear searches through this list, which is inefficient. This commit fixes all of the above problems by introducing a new predicate `is_any_keyword` in rustc and using it in rustdoc and rustfmt. It documents that it's not the right predicate in most cases.
1 parent 64abe8b commit 1564318

File tree

4 files changed

+31
-78
lines changed

4 files changed

+31
-78
lines changed

compiler/rustc_ast/src/token.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,8 @@ impl Token {
903903
self.is_non_raw_ident_where(|id| id.name == kw)
904904
}
905905

906-
/// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this token is an identifier equal to `kw` ignoring the case.
906+
/// Returns `true` if the token is a given keyword, `kw` or if `case` is `Insensitive` and this
907+
/// token is an identifier equal to `kw` ignoring the case.
907908
pub fn is_keyword_case(&self, kw: Symbol, case: Case) -> bool {
908909
self.is_keyword(kw)
909910
|| (case == Case::Insensitive
@@ -916,6 +917,11 @@ impl Token {
916917
self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
917918
}
918919

920+
/// Don't use this unless you're doing something very loose and heuristic-y.
921+
pub fn is_any_keyword(&self) -> bool {
922+
self.is_non_raw_ident_where(Ident::is_any_keyword)
923+
}
924+
919925
/// Returns true for reserved identifiers used internally for elided lifetimes,
920926
/// unnamed method parameters, crate root module, error recovery etc.
921927
pub fn is_special_ident(&self) -> bool {

compiler/rustc_parse/src/parser/diagnostics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -815,8 +815,8 @@ impl<'a> Parser<'a> {
815815

816816
// Otherwise, check the previous token with all the keywords as possible candidates.
817817
// This handles code like `Struct Human;` and `While a < b {}`.
818-
// We check the previous token only when the current token is an identifier to avoid false
819-
// positives like suggesting keyword `for` for `extern crate foo {}`.
818+
// We check the previous token only when the current token is an identifier to avoid
819+
// false positives like suggesting keyword `for` for `extern crate foo {}`.
820820
if let Some(misspelled_kw) = find_similar_kw(prev_ident, &all_keywords) {
821821
err.subdiagnostic(misspelled_kw);
822822
// We don't want other suggestions to be added as they are most likely meaningless

compiler/rustc_span/src/symbol.rs

+10
Original file line numberDiff line numberDiff line change
@@ -2589,6 +2589,11 @@ pub mod sym {
25892589
}
25902590

25912591
impl Symbol {
2592+
/// Don't use this unless you're doing something very loose and heuristic-y.
2593+
pub fn is_any_keyword(self) -> bool {
2594+
self >= kw::As && self <= kw::Yeet
2595+
}
2596+
25922597
fn is_special(self) -> bool {
25932598
self <= kw::Underscore
25942599
}
@@ -2645,6 +2650,11 @@ impl Symbol {
26452650
}
26462651

26472652
impl Ident {
2653+
/// Don't use this unless you're doing something very loose and heuristic-y.
2654+
pub fn is_any_keyword(self) -> bool {
2655+
self.name.is_any_keyword()
2656+
}
2657+
26482658
/// Returns `true` for reserved identifiers used internally for elided lifetimes,
26492659
/// unnamed method parameters, crate root module, error recovery etc.
26502660
pub fn is_special(self) -> bool {

src/tools/rustfmt/src/parse/macros/mod.rs

+12-75
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use rustc_ast::{ast, ptr};
44
use rustc_parse::MACRO_ARGUMENTS;
55
use rustc_parse::parser::{ForceCollect, Parser, Recovery};
66
use rustc_session::parse::ParseSess;
7-
use rustc_span::Symbol;
8-
use rustc_span::symbol::{self, kw};
7+
use rustc_span::symbol;
98

109
use crate::macros::MacroArg;
1110
use crate::rewrite::RewriteContext;
@@ -82,18 +81,18 @@ pub(crate) struct ParsedMacroArgs {
8281
}
8382

8483
fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
85-
for &keyword in RUST_KW.iter() {
86-
if parser.token.is_keyword(keyword)
87-
&& parser.look_ahead(1, |t| *t == TokenKind::Eof || *t == TokenKind::Comma)
88-
{
89-
parser.bump();
90-
return Some(MacroArg::Keyword(
91-
symbol::Ident::with_dummy_span(keyword),
92-
parser.prev_token.span,
93-
));
94-
}
84+
if parser.token.is_any_keyword()
85+
&& parser.look_ahead(1, |t| *t == TokenKind::Eof || *t == TokenKind::Comma)
86+
{
87+
let keyword = parser.token.ident().unwrap().0.name;
88+
parser.bump();
89+
Some(MacroArg::Keyword(
90+
symbol::Ident::with_dummy_span(keyword),
91+
parser.prev_token.span,
92+
))
93+
} else {
94+
None
9595
}
96-
None
9796
}
9897

9998
pub(crate) fn parse_macro_args(
@@ -169,65 +168,3 @@ pub(crate) fn parse_expr(
169168
let mut parser = build_parser(context, tokens);
170169
parser.parse_expr().ok()
171170
}
172-
173-
const RUST_KW: [Symbol; 59] = [
174-
kw::PathRoot,
175-
kw::DollarCrate,
176-
kw::Underscore,
177-
kw::As,
178-
kw::Box,
179-
kw::Break,
180-
kw::Const,
181-
kw::Continue,
182-
kw::Crate,
183-
kw::Else,
184-
kw::Enum,
185-
kw::Extern,
186-
kw::False,
187-
kw::Fn,
188-
kw::For,
189-
kw::If,
190-
kw::Impl,
191-
kw::In,
192-
kw::Let,
193-
kw::Loop,
194-
kw::Match,
195-
kw::Mod,
196-
kw::Move,
197-
kw::Mut,
198-
kw::Pub,
199-
kw::Ref,
200-
kw::Return,
201-
kw::SelfLower,
202-
kw::SelfUpper,
203-
kw::Static,
204-
kw::Struct,
205-
kw::Super,
206-
kw::Trait,
207-
kw::True,
208-
kw::Type,
209-
kw::Unsafe,
210-
kw::Use,
211-
kw::Where,
212-
kw::While,
213-
kw::Abstract,
214-
kw::Become,
215-
kw::Do,
216-
kw::Final,
217-
kw::Macro,
218-
kw::Override,
219-
kw::Priv,
220-
kw::Typeof,
221-
kw::Unsized,
222-
kw::Virtual,
223-
kw::Yield,
224-
kw::Dyn,
225-
kw::Async,
226-
kw::Try,
227-
kw::UnderscoreLifetime,
228-
kw::StaticLifetime,
229-
kw::Auto,
230-
kw::Catch,
231-
kw::Default,
232-
kw::Union,
233-
];

0 commit comments

Comments
 (0)