Skip to content

Replace builtin # with k# - #162232

Open
fmease wants to merge 6 commits into
rust-lang:mainfrom
fmease:yeet-builtin-hash
Open

fmease wants to merge 6 commits into
rust-lang:mainfrom
fmease:yeet-builtin-hash

Conversation

@fmease

@fmease fmease commented Sep 3, 2026 •

Copy link
Copy Markdown
Member

View all comments

Part of #153839. Also renames internal feature builtin_syntax to internal_syntax (without tombstoning) and keeps/reuses tracking issue #110680 (whose contents are going to get updated post merge).

Blocked on #161775 getting picked up by stage0 rustfmt (happened in PR #163483).

(No LLM was or will be used by me during the entire creation process of this PR)

@fmease fmease added S-blocked Status: Blocked on something else such as an RFC or other implementation work. rla-silenced Silences rust-log-analyzer postings to the PR it's added on. labels Sep 3, 2026
@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Sep 3, 2026
@fmease fmease removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Sep 3, 2026
Comment thread compiler/rustc_parse/src/parser/expr.rs Outdated
Comment thread compiler/rustc_span/src/symbol.rs
@fmease
fmease force-pushed the yeet-builtin-hash branch 2 times, most recently from 7415e73 to 1732079 Compare September 3, 2026 15:23
@rust-bors

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rust-bors

This comment has been minimized.

@fmease
fmease force-pushed the yeet-builtin-hash branch 3 times, most recently from 1e5e43a to 403ea1a Compare September 16, 2026 10:15
@rust-bors

This comment has been minimized.

@rust-bors

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 28, 2026
Implement forced keywords (`k#`)



Part of #153839. CC @dianne

Introduces a new token kind to Rust >=2021 that looks like `k#ident` and that is called *forced keyword (identifier)*. This is gated behind a new unstable feature called `forced_keywords`. This is backed by [compiler MCP 945](rust-lang/compiler-team#945).

~~The `ident` in `k#ident` *must* be a keyword (from any edition) or a weak/contextual keyword for the token to be valid.~~ The `ident` in `k#ident` needn't be a keyword to be lexically valid (CC #161775 (comment)).

---

What **won't** be done in this PR:

1. implementing forced keyword lifetimes (`'k#static`)
2. migrating away from built-in syntax `builtin # $ident($($tt)*)` / introducing `k#`-exclusive (weak) keywords
   * that'll be done in PR #162232 instead
3. allowing the user to force edition-dependent & context-dependent keywords to be keywords
   * re. edition-dependent: forcing them to be keywords even in editions where they're usually not a (strong) keyword (today, that only affects `gen` anyway IINM)
   * re. context-dependent: E.g., `union` is only "active" if it's followed by a non-reserved identifier and under this PR the same rules apply to `k#union` even though that's not necessary; changing it would result in better diagnostics (e.g., for `k#union struct {}`: `` error: expected item, found `k#union` `` => `` expected identifier, found keyword `struct` ``) and maybe also allow for disambiguation for other context-dependent keywords
4. extending the `proc_macro::Ident` API to allow users to programmatically create forced keywords (might never be added)

<sub>(No LLM was or will be used by me during the entire creation process of this PR)</sub>
pull Bot pushed a commit to xtqqczze/rust-lang-miri that referenced this pull request Sep 28, 2026
Implement forced keywords (`k#`)



Part of rust-lang/rust#153839. CC @dianne

Introduces a new token kind to Rust >=2021 that looks like `k#ident` and that is called *forced keyword (identifier)*. This is gated behind a new unstable feature called `forced_keywords`. This is backed by [compiler MCP 945](rust-lang/compiler-team#945).

~~The `ident` in `k#ident` *must* be a keyword (from any edition) or a weak/contextual keyword for the token to be valid.~~ The `ident` in `k#ident` needn't be a keyword to be lexically valid (CC rust-lang/rust#161775 (comment)).

---

What **won't** be done in this PR:

1. implementing forced keyword lifetimes (`'k#static`)
2. migrating away from built-in syntax `builtin # $ident($($tt)*)` / introducing `k#`-exclusive (weak) keywords
   * that'll be done in PR rust-lang/rust#162232 instead
3. allowing the user to force edition-dependent & context-dependent keywords to be keywords
   * re. edition-dependent: forcing them to be keywords even in editions where they're usually not a (strong) keyword (today, that only affects `gen` anyway IINM)
   * re. context-dependent: E.g., `union` is only "active" if it's followed by a non-reserved identifier and under this PR the same rules apply to `k#union` even though that's not necessary; changing it would result in better diagnostics (e.g., for `k#union struct {}`: `` error: expected item, found `k#union` `` => `` expected identifier, found keyword `struct` ``) and maybe also allow for disambiguation for other context-dependent keywords
4. extending the `proc_macro::Ident` API to allow users to programmatically create forced keywords (might never be added)

<sub>(No LLM was or will be used by me during the entire creation process of this PR)</sub>
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 14, 2026
@rustbot

This comment was marked as outdated.

@fmease

fmease commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

@rustbot reroll

@fmease

fmease commented Oct 14, 2026 •

Copy link
Copy Markdown
Member Author

Sorry about the pings, y'all. Maybe we should abandon the convention of calling the Symbol of weak / contextual keywords kw::$KeyWord and just call them sym::$keyword like normal symbols...

@fmease fmease removed the T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. label Oct 14, 2026
@rust-log-analyzer

This comment has been minimized.

@fmease
fmease force-pushed the yeet-builtin-hash branch from 26ab44f to 71ec952 Compare October 14, 2026 10:49
@rust-log-analyzer

This comment has been minimized.

@fmease
fmease force-pushed the yeet-builtin-hash branch 2 times, most recently from 218e623 to d8dbe1e Compare October 14, 2026 14:29
Comment on lines +2014 to +2018
// FIXME(deref_patterns, internal_syntax, forced_keywords, clippy):
// This should render `k#deref(...)` but unfortunately Clippy uses `pat_to_string`
// for the suggestions of its lint `unnested_or_patterns`. Smh fix Clippy to not
// rely on AST pretty printing `deref!(…)` for `Deref` patterns and please don't
// think about adding a flag to AST pretty to control the output.

@fmease fmease Oct 14, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly it turns out that Clippy relies on AST pretty for a structured diagnostic suggestion. Well, it's only lint unnested_or_patterns that relies on pat_to_string (since its inception). Clippy already features tests involving deref!(…).

I don't want to handle this right now, so I'm postponing it. I fear the proper solution would be for Clippy to maintain its own pattern printer.

View changes since the review

@rust-log-analyzer

This comment has been minimized.

@fmease
fmease force-pushed the yeet-builtin-hash branch from d8dbe1e to 6b86875 Compare October 14, 2026 15:33
@RalfJung

RalfJung commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Also renames internal feature builtin_syntax to internal_syntax

Is that the best name? Lots of things are "internal", we even have a category of "internal features".

This sounds more like "keyword syntax" to me. The code seems to also call it "forced keywords". So maybe forced_keywords?

@fmease

fmease commented Oct 14, 2026 •

Copy link
Copy Markdown
Member Author

Also renames internal feature builtin_syntax to internal_syntax

Is that the best name? Lots of things are "internal", we even have a category of "internal features".

This sounds more like "keyword syntax" to me. The code seems to also call it "forced keywords". So maybe forced_keywords?

Feature forced_keywords already exists (guarding k#ident itself) and is orthogonal to builtin_syntax / internal_syntax (guarding a class of internal syntactic constructs). Forced keywords are not just meant for internal features, more importantly they also exist so people can experiment with new keywords without breaking the world (CC only bounds, $expr is $pat, &own, etc.) which is practically motivated.

I consider the name "internal syntax" to be superior to "built-in syntax" because what even is "built-in syntax"? Every syntactic construct is "built-in". Sure, the token streams passed to macros may follow extra syntactic rules that are defined by the macro but that's at a slightly different level of abstraction.

Indeed, we have the concept of "internal features" -- "internal syntax" is a subset thereof / marked as such. I don't see how that is somehow an argument against the name. It's meant to guard a common "run-off-the-mill" class of syntactic constructs that are meant to be internal to the language / standard library. They're an alternative / successor to a certain class of built-in macros.

The only other internal syntaxes besides that are negative bounds !Bound & contract internals contract_ensures / contract_requires.

@RalfJung

Copy link
Copy Markdown
Member

Feature forced_keywords already exists (guarding k#ident itself)

Wait, what does internal_syntax guard then? After reading the PR description I thought it guards k#ident. Apparently I got that wrong?

@RalfJung

Copy link
Copy Markdown
Member

Oh I see, it guards some particular cases of "keywords" that we never intend to stabilize, as listed in #110680.
Yeah makes sense then, sorry for the noise. :)

@rust-log-analyzer

This comment has been minimized.

@fmease
fmease force-pushed the yeet-builtin-hash branch from 6b86875 to 77524bb Compare October 14, 2026 16:47
@rustbot

rustbot commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

rustfmt is developed in its own repository. If possible, consider making this change to rust-lang/rustfmt instead.

cc @rust-lang/rustfmt

@rustbot rustbot added the T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue. label Oct 14, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants