| use rustc_attr_ir::target::{MethodKind, Target}; | |
| use rustc_attr_ir::{AttributeKind, RustcDumpLayoutKind}; | |
| use rustc_feature::AttributeStability; | |
| 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 RustcDumpGenericsParser; | |
| impl NoArgsAttributeParser for RustcDumpGenericsParser { | |
| const PATH: &[Symbol] = &[sym::rustc_dump_generics]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| Allow(Target::Struct), | |
| Allow(Target::Enum), | |
| Allow(Target::Union), | |
| Allow(Target::Trait), | |
| Allow(Target::TraitAlias), | |
| Allow(Target::Fn), | |
| Allow(Target::Closure), | |
| Allow(Target::TyAlias), | |
| Allow(Target::Const), | |
| Allow(Target::AssocConst), | |
| Allow(Target::AssocTy), | |
| 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::Delegation { mac: false }), | |
| Allow(Target::Delegation { mac: true }), | |
| ]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpGenerics; | |
| } | |
| 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", "largest_niche", "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::largest_niche => RustcDumpLayoutKind::LargestNiche, | |
| 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; | |
| } |