rustc_attr_parsing/attributes/
traits.rs1use std::mem;
2
3use super::prelude::*;
4use crate::attributes::{
5 AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
6};
7use crate::context::{AcceptContext, Stage};
8use crate::parser::ArgParser;
9use crate::target_checking::Policy::{Allow, Warn};
10use crate::target_checking::{ALL_TARGETS, AllowedTargets};
11
12pub(crate) struct SkipDuringMethodDispatchParser;
13impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser {
14 const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch];
15 const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
16 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
17 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
18
19 const TEMPLATE: AttributeTemplate = template!(List: &["array, boxed_slice"]);
20
21 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
22 let mut array = false;
23 let mut boxed_slice = false;
24 let Some(args) = args.list() else {
25 cx.expected_list(cx.attr_span);
26 return None;
27 };
28 if args.is_empty() {
29 cx.expected_at_least_one_argument(args.span);
30 return None;
31 }
32 for arg in args.mixed() {
33 let Some(arg) = arg.meta_item() else {
34 cx.unexpected_literal(arg.span());
35 continue;
36 };
37 if let Err(span) = arg.args().no_args() {
38 cx.expected_no_args(span);
39 }
40 let path = arg.path();
41 let (key, skip): (Symbol, &mut bool) = match path.word_sym() {
42 Some(key @ sym::array) => (key, &mut array),
43 Some(key @ sym::boxed_slice) => (key, &mut boxed_slice),
44 _ => {
45 cx.expected_specific_argument(path.span(), &[sym::array, sym::boxed_slice]);
46 continue;
47 }
48 };
49 if mem::replace(skip, true) {
50 cx.duplicate_key(arg.span(), key);
51 }
52 }
53 Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span })
54 }
55}
56
57pub(crate) struct ParenSugarParser;
58impl<S: Stage> NoArgsAttributeParser<S> for ParenSugarParser {
59 const PATH: &[Symbol] = &[sym::rustc_paren_sugar];
60 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
61 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
62 const CREATE: fn(Span) -> AttributeKind = AttributeKind::ParenSugar;
63}
64
65pub(crate) struct TypeConstParser;
66impl<S: Stage> NoArgsAttributeParser<S> for TypeConstParser {
67 const PATH: &[Symbol] = &[sym::type_const];
68 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
69 const ALLOWED_TARGETS: AllowedTargets =
70 AllowedTargets::AllowList(&[Allow(Target::Const), Allow(Target::AssocConst)]);
71 const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst;
72}
73
74pub(crate) struct MarkerParser;
77impl<S: Stage> NoArgsAttributeParser<S> for MarkerParser {
78 const PATH: &[Symbol] = &[sym::marker];
79 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
80 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
81 Allow(Target::Trait),
82 Warn(Target::Field),
83 Warn(Target::Arm),
84 Warn(Target::MacroDef),
85 ]);
86 const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker;
87}
88
89pub(crate) struct DenyExplicitImplParser;
90impl<S: Stage> NoArgsAttributeParser<S> for DenyExplicitImplParser {
91 const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
92 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
93 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
94 const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl;
95}
96
97pub(crate) struct DoNotImplementViaObjectParser;
98impl<S: Stage> NoArgsAttributeParser<S> for DoNotImplementViaObjectParser {
99 const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object];
100 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
101 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
102 const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject;
103}
104
105pub(crate) struct SpecializationTraitParser;
108impl<S: Stage> NoArgsAttributeParser<S> for SpecializationTraitParser {
109 const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
110 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
111 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
112 const CREATE: fn(Span) -> AttributeKind = AttributeKind::SpecializationTrait;
113}
114
115pub(crate) struct UnsafeSpecializationMarkerParser;
116impl<S: Stage> NoArgsAttributeParser<S> for UnsafeSpecializationMarkerParser {
117 const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker];
118 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
119 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
120 const CREATE: fn(Span) -> AttributeKind = AttributeKind::UnsafeSpecializationMarker;
121}
122
123pub(crate) struct CoinductiveParser;
126impl<S: Stage> NoArgsAttributeParser<S> for CoinductiveParser {
127 const PATH: &[Symbol] = &[sym::rustc_coinductive];
128 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
129 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
130 const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive;
131}
132
133pub(crate) struct AllowIncoherentImplParser;
134impl<S: Stage> NoArgsAttributeParser<S> for AllowIncoherentImplParser {
135 const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
136 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
137 const ALLOWED_TARGETS: AllowedTargets =
138 AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
139 const CREATE: fn(Span) -> AttributeKind = AttributeKind::AllowIncoherentImpl;
140}
141
142pub(crate) struct FundamentalParser;
143impl<S: Stage> NoArgsAttributeParser<S> for FundamentalParser {
144 const PATH: &[Symbol] = &[sym::fundamental];
145 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
146 const ALLOWED_TARGETS: AllowedTargets =
147 AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
148 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
149}
150
151pub(crate) struct PointeeParser;
152impl<S: Stage> NoArgsAttributeParser<S> for PointeeParser {
153 const PATH: &[Symbol] = &[sym::pointee];
154 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
155 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); const CREATE: fn(Span) -> AttributeKind = AttributeKind::Pointee;
157}