| use std::mem; | |
| use rustc_feature::AttributeStability; | |
| use super::prelude::*; | |
| use crate::AttributeSafety; | |
| use crate::attributes::{NoArgsAttributeParser, SingleAttributeParser}; | |
| use crate::context::AcceptContext; | |
| use crate::parser::ArgParser; | |
| use crate::target_checking::AllowedTargets; | |
| use crate::target_checking::Policy::{Allow, Warn}; | |
| pub(crate) struct RustcSkipDuringMethodDispatchParser; | |
| impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser { | |
| const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> { | |
| let mut array = false; | |
| let mut boxed_slice = false; | |
| let args = cx.expect_list(args, cx.attr_span)?; | |
| if args.is_empty() { | |
| cx.adcx().expected_at_least_one_argument(args.span); | |
| return None; | |
| } | |
| for arg in args.mixed() { | |
| let Some(arg) = arg.meta_item() else { | |
| cx.adcx().expected_not_literal(arg.span()); | |
| continue; | |
| }; | |
| let _ = cx.expect_no_args(arg.args()); | |
| let path = arg.path(); | |
| let (key, skip): (Symbol, &mut bool) = match path.word_sym() { | |
| Some(key @ sym::array) => (key, &mut array), | |
| Some(key @ sym::boxed_slice) => (key, &mut boxed_slice), | |
| _ => { | |
| cx.adcx() | |
| .expected_specific_argument(path.span(), &[sym::array, sym::boxed_slice]); | |
| continue; | |
| } | |
| }; | |
| if mem::replace(skip, true) { | |
| cx.adcx().duplicate_key(arg.span(), key); | |
| } | |
| } | |
| Some(AttributeKind::RustcSkipDuringMethodDispatch { array, boxed_slice }) | |
| } | |
| } | |
| pub(crate) struct RustcParenSugarParser; | |
| impl NoArgsAttributeParser for RustcParenSugarParser { | |
| const PATH: &[Symbol] = &[sym::rustc_paren_sugar]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| const STABILITY: AttributeStability = unstable!(unboxed_closures); | |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar; | |
| } | |
| // Markers | |
| pub(crate) struct MarkerParser; | |
| impl NoArgsAttributeParser for MarkerParser { | |
| const PATH: &[Symbol] = &[sym::marker]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[ | |
| Allow(Target::Trait), | |
| Warn(Target::Field), | |
| Warn(Target::Arm), | |
| Warn(Target::MacroDef), | |
| ]); | |
| const STABILITY: AttributeStability = unstable!(marker_trait_attr); | |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Marker; | |
| } | |
| pub(crate) struct RustcDenyExplicitImplParser; | |
| impl NoArgsAttributeParser for RustcDenyExplicitImplParser { | |
| const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl; | |
| } | |
| pub(crate) struct RustcDynIncompatibleTraitParser; | |
| impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser { | |
| const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait; | |
| } | |
| // Specialization | |
| pub(crate) struct RustcSpecializationTraitParser; | |
| impl NoArgsAttributeParser for RustcSpecializationTraitParser { | |
| const PATH: &[Symbol] = &[sym::rustc_specialization_trait]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait; | |
| } | |
| pub(crate) struct RustcAllowLifetimeDependentSpecializationParser; | |
| impl NoArgsAttributeParser for RustcAllowLifetimeDependentSpecializationParser { | |
| const PATH: &[Symbol] = &[sym::rustc_allow_lifetime_dependent_specialization]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| const CREATE: fn(Span) -> AttributeKind = | |
| |_| AttributeKind::RustcAllowLifetimeDependentSpecialization; | |
| const SAFETY: AttributeSafety = AttributeSafety::Unsafe { | |
| note: "this attribute requires `unsafe` because lifetime constraints from \ | |
| the implementations of the trait are not considered when specializing", | |
| unsafe_since: None, | |
| }; | |
| } | |
| // Coherence | |
| pub(crate) struct RustcCoinductiveParser; | |
| impl NoArgsAttributeParser for RustcCoinductiveParser { | |
| const PATH: &[Symbol] = &[sym::rustc_coinductive]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive; | |
| } | |
| pub(crate) struct RustcAllowIncoherentImplParser; | |
| impl NoArgsAttributeParser for RustcAllowIncoherentImplParser { | |
| const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]); | |
| const STABILITY: AttributeStability = unstable!(rustc_attrs); | |
| const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl; | |
| } | |
| pub(crate) struct FundamentalParser; | |
| impl NoArgsAttributeParser for FundamentalParser { | |
| const PATH: &[Symbol] = &[sym::fundamental]; | |
| const ALLOWED_TARGETS: AllowedTargets<'_> = | |
| AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]); | |
| const STABILITY: AttributeStability = unstable!(fundamental); | |
| const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental; | |
| } |