rustc_attr_parsing/attributes/
traits.rs1use core::mem;
2
3use rustc_attr_data_structures::AttributeKind;
4use rustc_feature::{AttributeTemplate, template};
5use rustc_span::{Span, Symbol, sym};
6
7use crate::attributes::{
8 AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
9};
10use crate::context::{AcceptContext, Stage};
11use crate::parser::ArgParser;
12
13pub(crate) struct SkipDuringMethodDispatchParser;
14impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser {
15 const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch];
16 const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
17 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
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(), vec!["array", "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 CREATE: fn(Span) -> AttributeKind = AttributeKind::ParenSugar;
62}
63
64pub(crate) struct TypeConstParser;
65impl<S: Stage> NoArgsAttributeParser<S> for TypeConstParser {
66 const PATH: &[Symbol] = &[sym::type_const];
67 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
68 const CREATE: fn(Span) -> AttributeKind = AttributeKind::TypeConst;
69}
70
71pub(crate) struct MarkerParser;
74impl<S: Stage> NoArgsAttributeParser<S> for MarkerParser {
75 const PATH: &[Symbol] = &[sym::marker];
76 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
77 const CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker;
78}
79
80pub(crate) struct DenyExplicitImplParser;
81impl<S: Stage> NoArgsAttributeParser<S> for DenyExplicitImplParser {
82 const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
83 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
84 const CREATE: fn(Span) -> AttributeKind = AttributeKind::DenyExplicitImpl;
85}
86
87pub(crate) struct DoNotImplementViaObjectParser;
88impl<S: Stage> NoArgsAttributeParser<S> for DoNotImplementViaObjectParser {
89 const PATH: &[Symbol] = &[sym::rustc_do_not_implement_via_object];
90 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
91 const CREATE: fn(Span) -> AttributeKind = AttributeKind::DoNotImplementViaObject;
92}
93
94pub(crate) struct ConstTraitParser;
98impl<S: Stage> NoArgsAttributeParser<S> for ConstTraitParser {
99 const PATH: &[Symbol] = &[sym::const_trait];
100 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
101 const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstTrait;
102}
103
104pub(crate) struct SpecializationTraitParser;
107impl<S: Stage> NoArgsAttributeParser<S> for SpecializationTraitParser {
108 const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
109 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
110 const CREATE: fn(Span) -> AttributeKind = AttributeKind::SpecializationTrait;
111}
112
113pub(crate) struct UnsafeSpecializationMarkerParser;
114impl<S: Stage> NoArgsAttributeParser<S> for UnsafeSpecializationMarkerParser {
115 const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker];
116 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
117 const CREATE: fn(Span) -> AttributeKind = AttributeKind::UnsafeSpecializationMarker;
118}
119
120pub(crate) struct CoinductiveParser;
123impl<S: Stage> NoArgsAttributeParser<S> for CoinductiveParser {
124 const PATH: &[Symbol] = &[sym::rustc_coinductive];
125 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
126 const CREATE: fn(Span) -> AttributeKind = AttributeKind::Coinductive;
127}
128
129pub(crate) struct AllowIncoherentImplParser;
130impl<S: Stage> NoArgsAttributeParser<S> for AllowIncoherentImplParser {
131 const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
132 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
133 const CREATE: fn(Span) -> AttributeKind = AttributeKind::AllowIncoherentImpl;
134}
135
136pub(crate) struct CoherenceIsCoreParser;
137impl<S: Stage> NoArgsAttributeParser<S> for CoherenceIsCoreParser {
138 const PATH: &[Symbol] = &[sym::rustc_coherence_is_core];
139 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
140 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CoherenceIsCore;
141}
142
143pub(crate) struct FundamentalParser;
144impl<S: Stage> NoArgsAttributeParser<S> for FundamentalParser {
145 const PATH: &[Symbol] = &[sym::fundamental];
146 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
147 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
148}
149
150pub(crate) struct PointeeParser;
151impl<S: Stage> NoArgsAttributeParser<S> for PointeeParser {
152 const PATH: &[Symbol] = &[sym::pointee];
153 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
154 const CREATE: fn(Span) -> AttributeKind = AttributeKind::Pointee;
155}