diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index bde4904e9655d..3b7d25b43ba2f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -760,3 +760,53 @@ impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { ]); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility; } + +pub(crate) struct RustcSymbolName; + +impl SingleAttributeParser 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 = 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 { + 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 SingleAttributeParser 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 = 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 { + if let Err(span) = args.no_args() { + cx.expected_no_args(span); + return None; + } + Some(AttributeKind::RustcDefPath(cx.attr_span)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 9008e9edf9653..5b489d3064990 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -194,6 +194,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, @@ -204,6 +205,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 426363dcd7253..fa781a74c9e27 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -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), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index eb1e35ed9b257..14b54c129d3ea 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -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, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c207d7455f749..680a93908354c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -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 diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index 50935e7caf33c..8f842e0300113 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -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)), });