Skip to content

Keyword tweaks #138385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,11 +928,6 @@ impl Token {
self.is_non_raw_ident_where(Ident::is_path_segment_keyword)
}

/// Don't use this unless you're doing something very loose and heuristic-y.
pub fn is_any_keyword(&self) -> bool {
self.is_non_raw_ident_where(Ident::is_any_keyword)
}

/// Returns true for reserved identifiers used internally for elided lifetimes,
/// unnamed method parameters, crate root module, error recovery etc.
pub fn is_special_ident(&self) -> bool {
Expand Down
64 changes: 33 additions & 31 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ symbols! {
// documents (such as the Rust Reference) about whether it is a keyword
// (e.g. `_`).
//
// If you modify this list, adjust any relevant `Symbol::{is,can_be}_*` predicates and
// `used_keywords`.
// But this should rarely be necessary if the keywords are kept in alphabetic order.
// If you modify this list, adjust any relevant `Symbol::{is,can_be}_*`
// predicates and `used_keywords`. Also consider adding new keywords to the
// `ui/parser/raw/raw-idents.rs` test.
Keywords {
// Special reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc.
// Matching predicates: `is_any_keyword`, `is_special`/`is_reserved`
// Matching predicates: `is_special`/`is_reserved`
//
// Notes about `kw::Empty`:
// - Its use can blur the lines between "empty symbol" and "no symbol".
Expand All @@ -42,13 +42,16 @@ symbols! {
// present, it's better to use `sym::dummy` than `kw::Empty`, because
// it's clearer that it's intended as a dummy value, and more likely
// to be detected if it accidentally does get used.
// tidy-alphabetical-start
DollarCrate: "$crate",
Empty: "",
PathRoot: "{{root}}",
DollarCrate: "$crate",
Underscore: "_",
// tidy-alphabetical-end

// Keywords that are used in stable Rust.
// Matching predicates: `is_any_keyword`, `is_used_keyword_always`/`is_reserved`
// Matching predicates: `is_used_keyword_always`/`is_reserved`
// tidy-alphabetical-start
As: "as",
Break: "break",
Const: "const",
Expand Down Expand Up @@ -84,9 +87,11 @@ symbols! {
Use: "use",
Where: "where",
While: "while",
// tidy-alphabetical-end

// Keywords that are used in unstable Rust or reserved for future use.
// Matching predicates: `is_any_keyword`, `is_unused_keyword_always`/`is_reserved`
// Matching predicates: `is_unused_keyword_always`/`is_reserved`
// tidy-alphabetical-start
Abstract: "abstract",
Become: "become",
Box: "box",
Expand All @@ -99,41 +104,48 @@ symbols! {
Unsized: "unsized",
Virtual: "virtual",
Yield: "yield",
// tidy-alphabetical-end

// Edition-specific keywords that are used in stable Rust.
// Matching predicates: `is_any_keyword`, `is_used_keyword_conditional`/`is_reserved` (if
// Matching predicates: `is_used_keyword_conditional`/`is_reserved` (if
// the edition suffices)
// tidy-alphabetical-start
Async: "async", // >= 2018 Edition only
Await: "await", // >= 2018 Edition only
Dyn: "dyn", // >= 2018 Edition only
// tidy-alphabetical-end

// Edition-specific keywords that are used in unstable Rust or reserved for future use.
// Matching predicates: `is_any_keyword`, `is_unused_keyword_conditional`/`is_reserved` (if
// Matching predicates: `is_unused_keyword_conditional`/`is_reserved` (if
// the edition suffices)
// tidy-alphabetical-start
Gen: "gen", // >= 2024 Edition only
Try: "try", // >= 2018 Edition only

// NOTE: When adding new keywords, consider adding them to the ui/parser/raw/raw-idents.rs test.
// tidy-alphabetical-end

// "Lifetime keywords": regular keywords with a leading `'`.
// Matching predicates: `is_any_keyword`
UnderscoreLifetime: "'_",
// Matching predicates: none
// tidy-alphabetical-start
StaticLifetime: "'static",
UnderscoreLifetime: "'_",
// tidy-alphabetical-end

// Weak keywords, have special meaning only in specific contexts.
// Matching predicates: `is_any_keyword`
// Matching predicates: none
// tidy-alphabetical-start
Auto: "auto",
Builtin: "builtin",
Catch: "catch",
ContractEnsures: "contract_ensures",
ContractRequires: "contract_requires",
Default: "default",
MacroRules: "macro_rules",
Raw: "raw",
Reuse: "reuse",
ContractEnsures: "contract_ensures",
ContractRequires: "contract_requires",
Safe: "safe",
Union: "union",
Yeet: "yeet",
// tidy-alphabetical-end
}

// Pre-interned symbols that can be referred to with `rustc_span::sym::*`.
Expand Down Expand Up @@ -2677,11 +2689,6 @@ pub mod sym {
}

impl Symbol {
/// Don't use this unless you're doing something very loose and heuristic-y.
pub fn is_any_keyword(self) -> bool {
self >= kw::As && self <= kw::Yeet
}

fn is_special(self) -> bool {
self <= kw::Underscore
}
Expand All @@ -2690,14 +2697,14 @@ impl Symbol {
self >= kw::As && self <= kw::While
}

fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
(self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
}

fn is_unused_keyword_always(self) -> bool {
self >= kw::Abstract && self <= kw::Yield
}

fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool {
(self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018
}

fn is_unused_keyword_conditional(self, edition: impl Copy + FnOnce() -> Edition) -> bool {
self == kw::Gen && edition().at_least_rust_2024()
|| self == kw::Try && edition().at_least_rust_2018()
Expand Down Expand Up @@ -2738,11 +2745,6 @@ impl Symbol {
}

impl Ident {
/// Don't use this unless you're doing something very loose and heuristic-y.
pub fn is_any_keyword(self) -> bool {
self.name.is_any_keyword()
}

/// Returns `true` for reserved identifiers used internally for elided lifetimes,
/// unnamed method parameters, crate root module, error recovery etc.
pub fn is_special(self) -> bool {
Expand Down Expand Up @@ -2792,7 +2794,7 @@ impl Ident {
/// *Note:* Please update this if a new keyword is added beyond the current
/// range.
pub fn used_keywords(edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
(kw::Empty.as_u32()..kw::Yeet.as_u32())
(kw::DollarCrate.as_u32()..kw::Yeet.as_u32())
.filter_map(|kw| {
let kw = Symbol::new(kw);
if kw.is_used_keyword_always() || kw.is_used_keyword_conditional(edition) {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/rustfmt/src/parse/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub(crate) struct ParsedMacroArgs {
}

fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> {
if parser.token.is_any_keyword()
if parser.token.is_reserved_ident()
&& parser.look_ahead(1, |t| *t == TokenKind::Eof || *t == TokenKind::Comma)
{
let keyword = parser.token.ident().unwrap().0.name;
Expand Down
Loading