rustc_attr_parsing/attributes/
traits.rs1use std::mem;
2
3use super::prelude::*;
4use crate::attributes::{NoArgsAttributeParser, SingleAttributeParser};
5use crate::context::AcceptContext;
6use crate::parser::ArgParser;
7use crate::target_checking::AllowedTargets;
8use crate::target_checking::Policy::{Allow, Warn};
9
10pub(crate) struct RustcSkipDuringMethodDispatchParser;
11impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser {
12 const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch];
13 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
14
15 const TEMPLATE: AttributeTemplate = ::rustc_feature::AttributeTemplate {
word: false,
list: Some(&["array, boxed_slice"]),
one_of: &[],
name_value_str: None,
docs: None,
}template!(List: &["array, boxed_slice"]);
16
17 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
18 let mut array = false;
19 let mut boxed_slice = false;
20 let args = cx.expect_list(args, cx.attr_span)?;
21 if args.is_empty() {
22 cx.adcx().expected_at_least_one_argument(args.span);
23 return None;
24 }
25 for arg in args.mixed() {
26 let Some(arg) = arg.meta_item() else {
27 cx.adcx().expected_not_literal(arg.span());
28 continue;
29 };
30 let _ = cx.expect_no_args(arg.args());
31 let path = arg.path();
32 let (key, skip): (Symbol, &mut bool) = match path.word_sym() {
33 Some(key @ sym::array) => (key, &mut array),
34 Some(key @ sym::boxed_slice) => (key, &mut boxed_slice),
35 _ => {
36 cx.adcx()
37 .expected_specific_argument(path.span(), &[sym::array, sym::boxed_slice]);
38 continue;
39 }
40 };
41 if mem::replace(skip, true) {
42 cx.adcx().duplicate_key(arg.span(), key);
43 }
44 }
45 Some(AttributeKind::RustcSkipDuringMethodDispatch { array, boxed_slice })
46 }
47}
48
49pub(crate) struct RustcParenSugarParser;
50impl NoArgsAttributeParser for RustcParenSugarParser {
51 const PATH: &[Symbol] = &[sym::rustc_paren_sugar];
52 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
53 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar;
54}
55
56pub(crate) struct MarkerParser;
59impl NoArgsAttributeParser for MarkerParser {
60 const PATH: &[Symbol] = &[sym::marker];
61 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
62 Allow(Target::Trait),
63 Warn(Target::Field),
64 Warn(Target::Arm),
65 Warn(Target::MacroDef),
66 ]);
67 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Marker;
68}
69
70pub(crate) struct RustcDenyExplicitImplParser;
71impl NoArgsAttributeParser for RustcDenyExplicitImplParser {
72 const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
73 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
74 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl;
75}
76
77pub(crate) struct RustcDynIncompatibleTraitParser;
78impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser {
79 const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
80 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
81 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait;
82}
83
84pub(crate) struct RustcSpecializationTraitParser;
87impl NoArgsAttributeParser for RustcSpecializationTraitParser {
88 const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
89 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
90 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait;
91}
92
93pub(crate) struct RustcUnsafeSpecializationMarkerParser;
94impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser {
95 const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker];
96 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
97 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcUnsafeSpecializationMarker;
98}
99
100pub(crate) struct RustcCoinductiveParser;
103impl NoArgsAttributeParser for RustcCoinductiveParser {
104 const PATH: &[Symbol] = &[sym::rustc_coinductive];
105 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
106 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive;
107}
108
109pub(crate) struct RustcAllowIncoherentImplParser;
110impl NoArgsAttributeParser for RustcAllowIncoherentImplParser {
111 const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
112 const ALLOWED_TARGETS: AllowedTargets =
113 AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
114 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl;
115}
116
117pub(crate) struct FundamentalParser;
118impl NoArgsAttributeParser for FundamentalParser {
119 const PATH: &[Symbol] = &[sym::fundamental];
120 const ALLOWED_TARGETS: AllowedTargets =
121 AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
122 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
123}