| use rustc_hir::attrs::{AttributeKind, RustcDumpLayoutKind}; |
| use rustc_hir::{MethodKind, Target}; |
| use rustc_span::{Span, Symbol, sym}; |
| |
| use super::prelude::*; |
| use crate::context::Stage; |
| use crate::target_checking::AllowedTargets; |
| |
| pub(crate) struct RustcDumpUserArgsParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpUserArgsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_user_args]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs; |
| } |
| |
| pub(crate) struct RustcDumpDefParentsParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpDefParentsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_def_parents]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents; |
| } |
| |
| pub(crate) struct RustcDumpDefPathParser; |
| |
| impl<S: Stage> SingleAttributeParser<S> for RustcDumpDefPathParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_def_path]; |
| 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 TEMPLATE: AttributeTemplate = template!(Word); |
| fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { |
| if let Err(span) = args.no_args() { |
| cx.adcx().expected_no_args(span); |
| return None; |
| } |
| Some(AttributeKind::RustcDumpDefPath(cx.attr_span)) |
| } |
| } |
| |
| pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpHiddenTypeOfOpaquesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques; |
| } |
| |
| pub(crate) struct RustcDumpInferredOutlivesParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpInferredOutlivesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::Struct), |
| Allow(Target::Enum), |
| Allow(Target::Union), |
| Allow(Target::TyAlias), |
| ]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpInferredOutlives; |
| } |
| |
| pub(crate) struct RustcDumpItemBoundsParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpItemBoundsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds; |
| } |
| |
| pub(crate) struct RustcDumpLayoutParser; |
| |
| impl<S: Stage> CombineAttributeParser<S> for RustcDumpLayoutParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_layout]; |
| |
| type Item = RustcDumpLayoutKind; |
| |
| const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcDumpLayout(items); |
| |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::Struct), |
| Allow(Target::Enum), |
| Allow(Target::Union), |
| Allow(Target::TyAlias), |
| ]); |
| |
| const TEMPLATE: AttributeTemplate = |
| template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]); |
| fn extend( |
| cx: &mut AcceptContext<'_, '_, S>, |
| args: &ArgParser, |
| ) -> impl IntoIterator<Item = Self::Item> { |
| let ArgParser::List(items) = args else { |
| let attr_span = cx.attr_span; |
| cx.adcx().expected_list(attr_span, args); |
| return vec![]; |
| }; |
| |
| let mut result = Vec::new(); |
| for item in items.mixed() { |
| let Some(arg) = item.meta_item() else { |
| cx.adcx().expected_not_literal(item.span()); |
| continue; |
| }; |
| let Some(ident) = arg.ident() else { |
| cx.adcx().expected_identifier(arg.span()); |
| return vec![]; |
| }; |
| let kind = match ident.name { |
| sym::align => RustcDumpLayoutKind::Align, |
| sym::backend_repr => RustcDumpLayoutKind::BackendRepr, |
| sym::debug => RustcDumpLayoutKind::Debug, |
| sym::homogeneous_aggregate => RustcDumpLayoutKind::HomogenousAggregate, |
| sym::size => RustcDumpLayoutKind::Size, |
| _ => { |
| cx.adcx().expected_specific_argument( |
| ident.span, |
| &[ |
| sym::align, |
| sym::backend_repr, |
| sym::debug, |
| sym::homogeneous_aggregate, |
| sym::size, |
| ], |
| ); |
| continue; |
| } |
| }; |
| result.push(kind); |
| } |
| result |
| } |
| } |
| |
| pub(crate) struct RustcDumpObjectLifetimeDefaultsParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpObjectLifetimeDefaultsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::AssocConst), |
| Allow(Target::AssocTy), |
| Allow(Target::Const), |
| Allow(Target::Enum), |
| Allow(Target::Fn), |
| Allow(Target::ForeignFn), |
| Allow(Target::Impl { of_trait: false }), |
| Allow(Target::Impl { of_trait: true }), |
| Allow(Target::Method(MethodKind::Inherent)), |
| Allow(Target::Method(MethodKind::Trait { body: false })), |
| Allow(Target::Method(MethodKind::Trait { body: true })), |
| Allow(Target::Method(MethodKind::TraitImpl)), |
| Allow(Target::Struct), |
| Allow(Target::Trait), |
| Allow(Target::TraitAlias), |
| Allow(Target::TyAlias), |
| Allow(Target::Union), |
| ]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpObjectLifetimeDefaults; |
| } |
| |
| pub(crate) struct RustcDumpPredicatesParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpPredicatesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_predicates]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::AssocConst), |
| Allow(Target::AssocTy), |
| Allow(Target::Const), |
| Allow(Target::Delegation { mac: false }), |
| Allow(Target::Delegation { mac: true }), |
| Allow(Target::Enum), |
| Allow(Target::Fn), |
| Allow(Target::Impl { of_trait: false }), |
| Allow(Target::Impl { of_trait: true }), |
| Allow(Target::Method(MethodKind::Inherent)), |
| Allow(Target::Method(MethodKind::Trait { body: false })), |
| Allow(Target::Method(MethodKind::Trait { body: true })), |
| Allow(Target::Method(MethodKind::TraitImpl)), |
| Allow(Target::Struct), |
| Allow(Target::Trait), |
| Allow(Target::TraitAlias), |
| Allow(Target::TyAlias), |
| Allow(Target::Union), |
| ]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates; |
| } |
| |
| pub(crate) struct RustcDumpSymbolNameParser; |
| |
| impl<S: Stage> SingleAttributeParser<S> for RustcDumpSymbolNameParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_symbol_name]; |
| 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 TEMPLATE: AttributeTemplate = template!(Word); |
| fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> { |
| if let Err(span) = args.no_args() { |
| cx.adcx().expected_no_args(span); |
| return None; |
| } |
| Some(AttributeKind::RustcDumpSymbolName(cx.attr_span)) |
| } |
| } |
| |
| pub(crate) struct RustcDumpVariancesParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_variances]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::Enum), |
| Allow(Target::Fn), |
| Allow(Target::Method(MethodKind::Inherent)), |
| Allow(Target::Method(MethodKind::Trait { body: false })), |
| Allow(Target::Method(MethodKind::Trait { body: true })), |
| Allow(Target::Method(MethodKind::TraitImpl)), |
| Allow(Target::Struct), |
| Allow(Target::Union), |
| ]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariances; |
| } |
| |
| pub(crate) struct RustcDumpVariancesOfOpaquesParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesOfOpaquesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques; |
| } |
| |
| pub(crate) struct RustcDumpVtableParser; |
| |
| impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVtableParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_vtable]; |
| const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::Impl { of_trait: true }), |
| Allow(Target::TyAlias), |
| ]); |
| const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDumpVtable; |
| } |