Skip to content
Open
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
6 changes: 3 additions & 3 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1777,7 +1777,7 @@ pub enum ExprKind {
Lit(token::Lit),
/// A cast (e.g., `foo as f64`).
Cast(Box<Expr>, Box<Ty>),
/// A type ascription (e.g., `builtin # type_ascribe(42, usize)`).
/// A type ascription (e.g., `k#type_ascribe(42, usize)`).
///
/// Usually not written directly in user code but
/// indirectly via the macro `type_ascribe!(...)`.
Expand Down Expand Up @@ -1869,7 +1869,7 @@ pub enum ExprKind {
/// Output of the `asm!()` macro.
InlineAsm(Box<InlineAsm>),

/// An `offset_of` expression (e.g., `builtin # offset_of(Struct, field)`).
/// An `offset_of` expression (e.g., `k#offset_of(Struct, field)`).
///
/// Usually not written directly in user code but
/// indirectly via the macro `core::mem::offset_of!(...)`.
Expand Down Expand Up @@ -2568,7 +2568,7 @@ pub enum TyKind {
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
/// just as part of the type system.
Pat(Box<Ty>, Box<TyPat>),
/// A `field_of` expression (e.g., `builtin # field_of(Struct, field)`).
/// A `field_of` expression (e.g., `k#field_of(Struct, field)`).
///
/// Usually not written directly in user code but indirectly via the macro
/// `core::field::field_of!(...)`.
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, kind: IdentKind) -> bool {
// WARNING: Take care when modifying this function! It will change the stable(!) set of
// tokens that are allowed to match an `expr` nonterminal which is user observable.

// NOTE: We don't care about forced keywords that are gated behind `internal_syntax`.

let ident_token = Token::new(Ident(name, kind), span);

// FIXME: Remove `box` from this list given we officially no longer support box expressions
Expand Down Expand Up @@ -350,6 +352,8 @@ fn ident_can_begin_type(name: Symbol, span: Span, kind: IdentKind) -> bool {
// WARNING: Take care when modifying this function! It will change the stable(!) set of
// tokens that are allowed to match an `ty` nonterminal which is user observable.

// NOTE: We don't care about forced keywords that are gated behind `internal_syntax`.

let ident_token = Token::new(Ident(name, kind), span);

!ident_token.is_reserved_ident()
Expand Down Expand Up @@ -936,6 +940,10 @@ impl Token {
self.non_raw_ident().is_some_and(|id| id.name == kw)
}

pub fn is_forced_keyword(&self, kw: Symbol) -> bool {
self.ident().is_some_and(|(id, kind)| kind == IdentKind::ForcedKeyword && id.name == kw)
}

/// 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.
pub fn is_keyword_case(&self, kw: Symbol, case: Case) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {

// tidy-alphabetical-start
gate_all!(async_for_loop, "`for await` loops are experimental");
gate_all!(builtin_syntax, "`builtin #` syntax is unstable");
gate_all!(const_block_items, "const block items are experimental");
gate_all!(const_closures, "const closures are experimental");
gate_all!(const_trait_impl, "const trait impls are experimental");
Expand All @@ -451,6 +450,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(global_registration, "global registration is experimental");
gate_all!(guard_patterns, "guard patterns are experimental", "consider using match arm guards");
gate_all!(impl_restriction, "`impl` restrictions are experimental");
gate_all!(internal_syntax, "this syntax is internal");
gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental");
gate_all!(move_expr, "`move(expr)` syntax is experimental");
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,7 @@ impl<'a> State<'a> {
self.print_ty_pat(pat);
}
ast::TyKind::FieldOf(ty, variant, field) => {
self.word("builtin # field_of");
self.word("k#field_of");
self.popen();
let ib = self.ibox(0);
self.print_type(ty);
Expand Down Expand Up @@ -2011,6 +2011,11 @@ impl<'a> State<'a> {
self.pclose();
}
PatKind::Deref(inner) => {
// 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.
Comment on lines +2014 to +2018

@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

self.word("deref!");
self.popen();
self.print_pat(inner);
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_ast_pretty/src/pprust/state/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ impl<'a> State<'a> {
self.print_type(ty);
}
ast::ExprKind::Type(expr, ty) => {
self.word("builtin # type_ascribe");
self.word("k#type_ascribe");
self.popen();
let ib = self.ibox(0);
self.print_expr(expr, FixupContext::default());
Expand Down Expand Up @@ -777,12 +777,12 @@ impl<'a> State<'a> {
self.print_expr(result, fixup.rightmost_subexpression());
}
ast::ExprKind::InlineAsm(a) => {
// FIXME: Print `builtin # asm` once macro `asm` uses `builtin_syntax`.
// FIXME: Print `k#asm` once macro `asm` uses `internal_syntax`.
self.word(format!("{}!", a.asm_macro.macro_name()));
self.print_inline_asm(a);
}
ast::ExprKind::FormatArgs(fmt) => {
// FIXME: Print `builtin # format_args` once macro `format_args` uses `builtin_syntax`.
// FIXME: Print `k#format_args` once macro `format_args` uses `internal_syntax`.
self.word("format_args!");
self.popen();
let ib = self.ibox(0);
Expand All @@ -795,7 +795,7 @@ impl<'a> State<'a> {
self.pclose();
}
ast::ExprKind::OffsetOf(container, fields) => {
self.word("builtin # offset_of");
self.word("k#offset_of");
self.popen();
let ib = self.ibox(0);
self.print_type(container);
Expand Down Expand Up @@ -855,10 +855,9 @@ impl<'a> State<'a> {
self.print_block_with_attrs(blk, attrs, cb, ib)
}
ast::ExprKind::UnsafeBinderCast(kind, expr, ty) => {
self.word("builtin # ");
match kind {
ast::UnsafeBinderCastKind::Wrap => self.word("wrap_binder"),
ast::UnsafeBinderCastKind::Unwrap => self.word("unwrap_binder"),
ast::UnsafeBinderCastKind::Wrap => self.word("k#wrap_binder"),
ast::UnsafeBinderCastKind::Unwrap => self.word("k#unwrap_binder"),
}
self.popen();
let ib = self.ibox(0);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ impl<'a> State<'a> {
self.bclose(item.span, empty, cb);
}
ast::ItemKind::GlobalAsm(asm) => {
// FIXME: Print `builtin # global_asm` once macro `global_asm` uses `builtin_syntax`.
// FIXME: Print `k#global_asm` once macro `global_asm` uses `internal_syntax`.
let (cb, ib) = self.head(visibility_qualified(&item.vis, "global_asm!"));
self.print_inline_asm(asm);
self.word(";");
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_ir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ language_item_table! {
Unsize, sym::unsize, unsize_trait, Target::Trait, GenericRequirement::Minimum(1);
AlignOf, sym::mem_align_const, align_const, Target::AssocConst(AssocCtxt::Trait), GenericRequirement::Exact(0);
SizeOf, sym::mem_size_const, size_const, Target::AssocConst(AssocCtxt::Trait), GenericRequirement::Exact(0);
OffsetOf, sym::offset_of, offset_of, Target::Fn, GenericRequirement::Exact(1);
OffsetOf, kw::OffsetOf, offset_of, Target::Fn, GenericRequirement::Exact(1);
/// Trait injected by `#[derive(PartialEq)]`, (i.e. "Partial EQ").
StructuralPeq, sym::structural_peq, structural_peq_trait, Target::Trait, GenericRequirement::None;
Copy, sym::copy, copy_trait, Target::Trait, GenericRequirement::Exact(0);
Expand Down Expand Up @@ -239,7 +239,7 @@ language_item_table! {
Complex, sym::complex, complex, Target::Struct, GenericRequirement::Exact(1);
PpcF128, sym::ppcf128, ppcf128, Target::Struct, GenericRequirement::None;

Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
Deref, kw::Deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0);
DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0);
DerefTarget, sym::deref_target, deref_target, Target::AssocTy(AssocCtxt::Trait), GenericRequirement::None;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
use rustc_middle::ty;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{FloatTy, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::{Symbol, bug, span_bug, sym};
use rustc_span::{Symbol, bug, kw, span_bug, sym};
use tracing::trace;

use super::memory::MemoryKind;
Expand Down Expand Up @@ -232,7 +232,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let val = layout.align.bytes();
self.write_scalar(Scalar::from_target_usize(val, self), dest)?;
}
sym::offset_of => {
kw::OffsetOf => {
let tp_ty = instance.args.type_at(0);

let variant = self.read_scalar(&args[0])?.to_u32()?;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,15 +299,15 @@ declare_features! (
/// Allows features specific to auto traits.
/// Renamed from `optin_builtin_traits`.
(unstable, auto_traits, "1.50.0", Some(13231)),
/// Allows builtin # foo() syntax
(internal, builtin_syntax, "1.71.0", Some(110680)),
/// Allows `#[doc(notable_trait)]`.
/// Renamed from `doc_spotlight`.
(unstable, doc_notable_trait, "1.52.0", Some(45040)),
/// Allows using the `may_dangle` attribute (RFC 1327).
(unstable, dropck_eyepatch, "1.10.0", Some(34761)),
/// Allows using the `#[fundamental]` attribute.
(unstable, fundamental, "1.0.0", Some(29635)),
/// Allows internal syntax.
(internal, internal_syntax, "CURRENT_RUSTC_VERSION", Some(110680)),
/// Allows using `#[link_name="llvm.*"]`.
(internal, link_llvm_intrinsics, "1.0.0", Some(29602)),
/// Allows using the `#[linkage = ".."]` attribute.
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_hir as hir;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_span::{Span, Symbol, sym};
use rustc_span::{Span, Symbol, kw, sym};

use crate::check::check_function_signature;
use crate::diagnostics::{UnrecognizedIntrinsicFunction, WrongNumberOfGenericArgumentsToIntrinsic};
Expand Down Expand Up @@ -66,6 +66,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
// safe extern fns are otherwise unprecedented.

// tidy-alphabetical-start
| kw::OffsetOf
| sym::abort_immediate
| sym::add_with_overflow
| sym::aggregate_raw_ptr
Expand Down Expand Up @@ -152,7 +153,6 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::needs_drop
| sym::offload
| sym::offload_get_num_devices
| sym::offset_of
| sym::overflow_checks
| sym::powf16
| sym::powf32
Expand Down Expand Up @@ -298,7 +298,7 @@ pub(crate) fn check_intrinsic_type(
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
}
sym::type_id_size_of => (0, 0, vec![type_id_ty()], Ty::new_option(tcx, tcx.types.usize)),
sym::offset_of => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize),
kw::OffsetOf => (1, 0, vec![tcx.types.u32, tcx.types.u32], tcx.types.usize),
sym::field_offset => (1, 0, vec![], tcx.types.usize),
sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/place_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_middle::ty::adjustment::{
OverloadedDeref, PointerCoercion,
};
use rustc_middle::ty::{self, Ty};
use rustc_span::{Span, span_bug, sym};
use rustc_span::{Span, kw, span_bug, sym};
use tracing::debug;

use crate::method::{MethodCallee, TreatNotYetDefinedOpaques};
Expand Down Expand Up @@ -203,7 +203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("try_overloaded_place_op({:?},{:?},{:?})", span, base_ty, op);

let (Some(imm_tr), imm_op) = (match op {
PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), sym::deref),
PlaceOp::Deref => (self.tcx.lang_items().deref_trait(), kw::Deref),
PlaceOp::Index => (self.tcx.lang_items().index_trait(), sym::index),
}) else {
// Bail if `Deref` or `Index` isn't defined.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/builder/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt};
use rustc_span::def_id::DefId;
use rustc_span::{DUMMY_SP, Span, Spanned, Symbol, bug, sym};
use rustc_span::{DUMMY_SP, Span, Spanned, Symbol, bug, kw, sym};
use tracing::{debug, instrument};

use crate::builder::Builder;
Expand Down Expand Up @@ -343,7 +343,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
span: Span,
) {
let (trait_item, method) = match mutability {
Mutability::Not => (LangItem::Deref, sym::deref),
Mutability::Not => (LangItem::Deref, kw::Deref),
Mutability::Mut => (LangItem::DerefMut, sym::deref_mut),
};
let borrow_kind = super::util::ref_pat_borrow_kind(mutability);
Expand Down
15 changes: 0 additions & 15 deletions compiler/rustc_parse/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4086,21 +4086,6 @@ impl IntoDiagArg for Case {
}
}

#[derive(Diagnostic)]
#[diag("unknown `builtin #` construct `{$name}`")]
pub(crate) struct UnknownBuiltinConstruct {
#[primary_span]
pub span: Span,
pub name: Ident,
}

#[derive(Diagnostic)]
#[diag("expected identifier after `builtin #`")]
pub(crate) struct ExpectedBuiltinIdent {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("static items may not have generic parameters")]
pub(crate) struct StaticWithGenerics {
Expand Down
Loading
Loading