Port #[rustc_symbol_name] and #[rustc_def_path] to attr parser

This commit is contained in:
Edvin Bryntesson 2026-01-11 01:59:43 +01:00
parent efc9e1b50c
commit 10f0c2d579
No known key found for this signature in database
6 changed files with 77 additions and 12 deletions

View file

@ -760,3 +760,53 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility;
}
pub(crate) struct RustcSymbolName;
impl<S: Stage> SingleAttributeParser<S> for RustcSymbolName {
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const PATH: &[Symbol] = &[sym::rustc_symbol_name];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
cx.expected_no_args(span);
return None;
}
Some(AttributeKind::RustcSymbolName(cx.attr_span))
}
}
pub(crate) struct RustcDefPath;
impl<S: Stage> SingleAttributeParser<S> for RustcDefPath {
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Fn),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::Impl { of_trait: false }),
]);
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const PATH: &[Symbol] = &[sym::rustc_def_path];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if let Err(span) = args.no_args() {
cx.expected_no_args(span);
return None;
}
Some(AttributeKind::RustcDefPath(cx.attr_span))
}
}

View file

@ -194,6 +194,7 @@ attribute_parsers!(
Single<RustcAbiParser>,
Single<RustcAllocatorZeroedVariantParser>,
Single<RustcBuiltinMacroParser>,
Single<RustcDefPath>,
Single<RustcForceInlineParser>,
Single<RustcIfThisChangedParser>,
Single<RustcLayoutScalarValidRangeEndParser>,
@ -204,6 +205,7 @@ attribute_parsers!(
Single<RustcObjectLifetimeDefaultParser>,
Single<RustcScalableVectorParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<RustcSymbolName>,
Single<SanitizeParser>,
Single<ShouldPanicParser>,
Single<SkipDuringMethodDispatchParser>,

View file

@ -1081,6 +1081,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_deallocator]`
RustcDeallocator,
/// Represents `#[rustc_def_path]`
RustcDefPath(Span),
/// Represents `#[rustc_deny_explicit_impl]`.
RustcDenyExplicitImpl(Span),
@ -1218,6 +1221,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_std_internal_symbol]`.
RustcStdInternalSymbol(Span),
/// Represents `#[rustc_symbol_name]`
RustcSymbolName(Span),
/// Represents `#[rustc_then_this_would_need]`
RustcThenThisWouldNeed(Span, ThinVec<Ident>),

View file

@ -105,6 +105,7 @@ impl AttributeKind {
RustcConstStability { .. } => Yes,
RustcConstStabilityIndirect => No,
RustcDeallocator => No,
RustcDefPath(..) => No,
RustcDenyExplicitImpl(..) => No,
RustcDummy => No,
RustcDumpDefParents => No,
@ -149,6 +150,7 @@ impl AttributeKind {
RustcSkipDuringMethodDispatch { .. } => No,
RustcSpecializationTrait(..) => No,
RustcStdInternalSymbol(..) => No,
RustcSymbolName(..) => Yes,
RustcThenThisWouldNeed(..) => No,
RustcUnsafeSpecializationMarker(..) => No,
RustcVariance => No,

View file

@ -300,6 +300,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcConfusables { .. }
| AttributeKind::RustcConstStabilityIndirect
| AttributeKind::RustcDeallocator
| AttributeKind::RustcDefPath(..)
| AttributeKind::RustcDenyExplicitImpl(..)
| AttributeKind::RustcDummy
| AttributeKind::RustcDumpDefParents
@ -340,6 +341,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcSkipDuringMethodDispatch { .. }
| AttributeKind::RustcSpecializationTrait(..)
| AttributeKind::RustcStdInternalSymbol (..)
| AttributeKind::RustcSymbolName(..)
| AttributeKind::RustcThenThisWouldNeed(..)
| AttributeKind::RustcUnsafeSpecializationMarker(..)
| AttributeKind::RustcVariance
@ -403,10 +405,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::rustc_strict_coherence
| sym::rustc_mir
| sym::rustc_outlives
| sym::rustc_symbol_name
| sym::rustc_evaluate_where_clauses
| sym::rustc_delayed_bug_from_inside_query
| sym::rustc_def_path
| sym::rustc_partition_reused
| sym::rustc_partition_codegened
| sym::rustc_expected_cgu_reuse

View file

@ -4,16 +4,14 @@
//! def-path. This is used for unit testing the code that generates
//! paths etc in all kinds of annoying scenarios.
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::find_attr;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{GenericArgs, Instance, TyCtxt};
use rustc_span::{Symbol, sym};
use crate::errors::{Kind, TestOutput};
const SYMBOL_NAME: Symbol = sym::rustc_symbol_name;
const DEF_PATH: Symbol = sym::rustc_def_path;
pub fn report_symbol_names(tcx: TyCtxt<'_>) {
// if the `rustc_attrs` feature is not enabled, then the
// attributes we are interested in cannot be present anyway, so
@ -54,7 +52,11 @@ impl SymbolNamesTest<'_> {
// The formatting of `tag({})` is chosen so that tests can elect
// to test the entirety of the string, if they choose, or else just
// some subset.
for attr in tcx.get_attrs(def_id, SYMBOL_NAME) {
if let Some(attr_span) = find_attr!(
tcx.get_all_attrs(def_id),
AttributeKind::RustcSymbolName(span) => span
) {
let def_id = def_id.to_def_id();
let instance = Instance::new_raw(
def_id,
@ -62,27 +64,30 @@ impl SymbolNamesTest<'_> {
);
let mangled = tcx.symbol_name(instance);
tcx.dcx().emit_err(TestOutput {
span: attr.span(),
span: *attr_span,
kind: Kind::SymbolName,
content: format!("{mangled}"),
});
if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) {
tcx.dcx().emit_err(TestOutput {
span: attr.span(),
span: *attr_span,
kind: Kind::Demangling,
content: format!("{demangling}"),
});
tcx.dcx().emit_err(TestOutput {
span: attr.span(),
span: *attr_span,
kind: Kind::DemanglingAlt,
content: format!("{demangling:#}"),
});
}
}
for attr in tcx.get_attrs(def_id, DEF_PATH) {
if let Some(attr_span) = find_attr!(
tcx.get_all_attrs(def_id),
AttributeKind::RustcDefPath(span) => span
) {
tcx.dcx().emit_err(TestOutput {
span: attr.span(),
span: *attr_span,
kind: Kind::DefPath,
content: with_no_trimmed_paths!(tcx.def_path_str(def_id)),
});