Repository navigation
Description
This is a tracking issue for the internal feature internal syntax.
It's gated behind #![feature(internal_syntax)] and hosts an assortment of syntaxes that conventionally follow the scheme k#IDENT($( $tt )*) where IDENT is the name of the construct and k# (from MCP 945) forces IDENT to be interpreted as a keyword.
This feature once used to be called builtin_syntax and the individual constructs used to be prefixed with builtin # instead of k#. It was originally proposed in MCP 580.
Usually, these internal syntactic constructs are then wrapped by & exposed via a non-internal macro in the library core. The macro is usually a decl macro 2.0 that's annotated with #[diagnostic::opaque] & bears the same name as the internal construct.
About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
- Implement the scaffolding for the
builtin #syntax - Replace
builtin #withk# - Migrate all built-in macros that qualify to wrapper macros containing internal syntax
-
asm(ast::ExprKind::InlineAsm) -
format_args(ast::ExprKind::FormatArgs) -
gca(ast::{Expr,Type}Kind::GcaMacro(needs renaming)) -
global_asm(ast::ItemKind::GlobalAsm) -
include_bytes(ast::ExprKind::IncludedBytes) -
naked_asm(ast::ExprKind::InlineAsm) -
offset_of(ast::ExprKind::OffsetOf) -
pattern_type(ast::TyKind::Pat) -
type_ascribe(ast::ExprKind::Type) -
view_type(ast::TypeKind::View)
-
- Maybe migrate certain (unstable) temporary syntactic constructs to internal syntax unless it's considered too churn-y for users of the language
-
do yeet(ast::ExprKind::Yeet)
-
Reference
For reference, here's a list of all current internal syntactic constructs:
deref(ast::PatKind::Deref)field_of(ast::TyKind::FieldOf)offset_of(ast::ExprKind::OffsetOf)type_ascribe(ast::ExprKind::Type)unwrap_binder(ast::ExprKind::UnsafeBinderCast(Unwrap))wrap_binder(ast::ExprKind::UnsafeBinderCast(Wrap))
Unresolved questions
None so far.
Implementation history
- Implement builtin # syntax and use it for offset_of!(...) #110694
- Implement macro-based deref!() syntax for deref patterns #122793
- Make
type_ascribe!not a built-in #122806 - Mark
builtin_syntaxas internal #127622 - Add AST support for unsafe binders #134140
- add field representing types #152730
- Replace
builtin #withk##162232
PSA: The feature has been renamed from builtin_syntax to internal_syntax (without tombstoning) and the overarching syntax has been changed from builtin # IDENT(TTS) to k#IDENT(TTS) where k# is a Rust>=2021 identifier prefix that turns the identifier into a so-called forced keyword meaning k#IDENT is a single lexical element unlike builtin # (see also MCP 945).
The change will be effective with the upcoming release of nightly-2026-11-05 (v1.101.0).
Activity
Rollup merge of rust-lang#110694 - est31:builtin, r=petrochenkov
[-]Tracking Issue for builtin# syntax[/-][+]Tracking Issue for builtin # syntax[/+]fix(deps): update rust crate syn to v2 (#2512)
Rollup merge of rust-lang#127622 - compiler-errors:builtin-internal, …
Unrolled build for rust-lang#127622
Rollup merge of rust-lang#162232 - fmease:yeet-builtin-hash, r=JohnTitor
Rollup merge of rust-lang#162232 - fmease:yeet-builtin-hash, r=JohnTitor
Rollup merge of rust-lang#162232 - fmease:yeet-builtin-hash, r=JohnTitor
Rollup merge of rust-lang#162232 - fmease:yeet-builtin-hash, r=JohnTitor
Rollup merge of rust-lang#162232 - fmease:yeet-builtin-hash, r=JohnTitor
Rollup merge of rust-lang#162232 - fmease:yeet-builtin-hash, r=JohnTitor
Unrolled build for #162232 in rollup 165436
[-]Tracking Issue for builtin # syntax[/-][+]Tracking issue for internal syntax[/+]fmease commentedon Nov 4, 2026
PSA: The feature has been renamed from
builtin_syntaxtointernal_syntax(without tombstoning) and the overarching syntax has been changed frombuiltin # IDENT(TTS)tok#IDENT(TTS)wherek#is a Rust>=2021 identifier prefix that turns the identifier into a so-called forced keyword meaningk#IDENTis a single lexical element unlikebuiltin #(see also MCP 945).The change will be effective with the upcoming release of nightly-2026-11-05 (v1.101.0).