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