rustc_attr_parsing/attributes/
traits.rs

1use 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
71// Markers
72
73pub(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
94// FIXME(const_trait_impl): remove this
95// Const traits
96
97pub(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
104// Specialization
105
106pub(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
120// Coherence
121
122pub(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}