| use rustc_feature::AttributeStability; |
| use rustc_hir::attrs::{AttributeKind, RustcDumpLayoutKind}; |
| use rustc_hir::{MethodKind, Target}; |
| use rustc_span::{Span, Symbol, sym}; |
| |
| use super::prelude::*; |
| use crate::target_checking::AllowedTargets; |
| |
| pub(crate) struct RustcDumpUserArgsParser; |
| |
| impl NoArgsAttributeParser for RustcDumpUserArgsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_user_args]; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs; |
| } |
| |
| pub(crate) struct RustcDumpDefParentsParser; |
| |
| impl NoArgsAttributeParser for RustcDumpDefParentsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_def_parents]; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents; |
| } |
| |
| pub(crate) struct RustcDumpDefPathParser; |
| |
| impl SingleAttributeParser 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 TEMPLATE: AttributeTemplate = template!(Word); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { |
| cx.expect_no_args(args)?; |
| Some(AttributeKind::RustcDumpDefPath(cx.attr_span)) |
| } |
| } |
| |
| pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser; |
| |
| impl NoArgsAttributeParser for RustcDumpHiddenTypeOfOpaquesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques]; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques; |
| } |
| |
| pub(crate) struct RustcDumpInferredOutlivesParser; |
| |
| impl NoArgsAttributeParser for RustcDumpInferredOutlivesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives]; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::Struct), |
| Allow(Target::Enum), |
| Allow(Target::Union), |
| Allow(Target::TyAlias), |
| ]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpInferredOutlives; |
| } |
| |
| pub(crate) struct RustcDumpItemBoundsParser; |
| |
| impl NoArgsAttributeParser for RustcDumpItemBoundsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds]; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds; |
| } |
| |
| pub(crate) struct RustcDumpLayoutParser; |
| |
| impl CombineAttributeParser 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"]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| |
| fn extend( |
| cx: &mut AcceptContext<'_, '_>, |
| args: &ArgParser, |
| ) -> impl IntoIterator<Item = Self::Item> { |
| let Some(items) = cx.expect_list(args, cx.attr_span) else { |
| return vec![]; |
| }; |
| |
| let mut result = Vec::new(); |
| for item in items.mixed() { |
| let Some(arg) = item.meta_item_no_args() 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 NoArgsAttributeParser for RustcDumpObjectLifetimeDefaultsParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults]; |
| 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 STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpObjectLifetimeDefaults; |
| } |
| |
| pub(crate) struct RustcDumpPredicatesParser; |
| |
| impl NoArgsAttributeParser for RustcDumpPredicatesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_predicates]; |
| 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 STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates; |
| } |
| |
| pub(crate) struct RustcDumpSymbolNameParser; |
| |
| impl SingleAttributeParser 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 TEMPLATE: AttributeTemplate = template!(Word); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { |
| cx.expect_no_args(args)?; |
| Some(AttributeKind::RustcDumpSymbolName(cx.attr_span)) |
| } |
| } |
| |
| pub(crate) struct RustcDumpVariancesParser; |
| |
| impl NoArgsAttributeParser for RustcDumpVariancesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_variances]; |
| 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 STABILITY: AttributeStability = unstable!( |
| rustc_attrs, |
| "the `#[rustc_dump_variances]` attribute is used for rustc unit tests" |
| ); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariances; |
| } |
| |
| pub(crate) struct RustcDumpVariancesOfOpaquesParser; |
| |
| impl NoArgsAttributeParser for RustcDumpVariancesOfOpaquesParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques]; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques; |
| } |
| |
| pub(crate) struct RustcDumpVtableParser; |
| |
| impl NoArgsAttributeParser for RustcDumpVtableParser { |
| const PATH: &[Symbol] = &[sym::rustc_dump_vtable]; |
| const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ |
| Allow(Target::Impl { of_trait: true }), |
| Allow(Target::TyAlias), |
| ]); |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); |
| const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDumpVtable; |
| } |