rustc_attr_parsing/attributes/
traits.rs1use std::mem;
2
3use rustc_feature::AttributeStability;
4
5use super::prelude::*;
6use crate::AttributeSafety;
7use crate::attributes::{NoArgsAttributeParser, SingleAttributeParser};
8use crate::context::AcceptContext;
9use crate::parser::ArgParser;
10use crate::target_checking::AllowedTargets;
11use crate::target_checking::Policy::{Allow, Warn};
12
13pub(crate) struct RustcSkipDuringMethodDispatchParser;
14impl SingleAttributeParser for RustcSkipDuringMethodDispatchParser {
15 const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch];
16 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
17
18 const TEMPLATE: AttributeTemplate = crate::AttributeTemplate {
word: false,
list: Some(&["array, boxed_slice"]),
one_of: &[],
name_value_str: None,
docs: None,
}template!(List: &["array, boxed_slice"]);
19 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
gate_check: rustc_feature::Features::rustc_attrs,
notes: &[],
}unstable!(rustc_attrs);
20
21 fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
22 let mut array = false;
23 let mut boxed_slice = false;
24 let args = cx.expect_list(args, cx.attr_span)?;
25 if args.is_empty() {
26 cx.adcx().expected_at_least_one_argument(args.span);
27 return None;
28 }
29 for arg in args.mixed() {
30 let Some(arg) = arg.meta_item() else {
31 cx.adcx().expected_not_literal(arg.span());
32 continue;
33 };
34 let _ = cx.expect_no_args(arg.args());
35 let path = arg.path();
36 let (key, skip): (Symbol, &mut bool) = match path.word_sym() {
37 Some(key @ sym::array) => (key, &mut array),
38 Some(key @ sym::boxed_slice) => (key, &mut boxed_slice),
39 _ => {
40 cx.adcx()
41 .expected_specific_argument(path.span(), &[sym::array, sym::boxed_slice]);
42 continue;
43 }
44 };
45 if mem::replace(skip, true) {
46 cx.adcx().duplicate_key(arg.span(), key);
47 }
48 }
49 Some(AttributeKind::RustcSkipDuringMethodDispatch { array, boxed_slice })
50 }
51}
52
53pub(crate) struct RustcParenSugarParser;
54impl NoArgsAttributeParser for RustcParenSugarParser {
55 const PATH: &[Symbol] = &[sym::rustc_paren_sugar];
56 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
57 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::unboxed_closures,
gate_check: rustc_feature::Features::unboxed_closures,
notes: &[],
}unstable!(unboxed_closures);
58 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcParenSugar;
59}
60
61pub(crate) struct MarkerParser;
64impl NoArgsAttributeParser for MarkerParser {
65 const PATH: &[Symbol] = &[sym::marker];
66 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[
67 Allow(Target::Trait),
68 Warn(Target::Field),
69 Warn(Target::Arm),
70 Warn(Target::MacroDef),
71 ]);
72 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::marker_trait_attr,
gate_check: rustc_feature::Features::marker_trait_attr,
notes: &[],
}unstable!(marker_trait_attr);
73 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Marker;
74}
75
76pub(crate) struct RustcDenyExplicitImplParser;
77impl NoArgsAttributeParser for RustcDenyExplicitImplParser {
78 const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
79 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
80 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
gate_check: rustc_feature::Features::rustc_attrs,
notes: &[],
}unstable!(rustc_attrs);
81 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl;
82}
83
84pub(crate) struct RustcDynIncompatibleTraitParser;
85impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser {
86 const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
87 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
88 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
gate_check: rustc_feature::Features::rustc_attrs,
notes: &[],
}unstable!(rustc_attrs);
89 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait;
90}
91
92pub(crate) struct RustcSpecializationTraitParser;
95impl NoArgsAttributeParser for RustcSpecializationTraitParser {
96 const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
97 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
98 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
gate_check: rustc_feature::Features::rustc_attrs,
notes: &[],
}unstable!(rustc_attrs);
99 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait;
100}
101
102pub(crate) struct RustcAllowLifetimeDependentSpecializationParser;
103impl NoArgsAttributeParser for RustcAllowLifetimeDependentSpecializationParser {
104 const PATH: &[Symbol] = &[sym::rustc_allow_lifetime_dependent_specialization];
105 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
106 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
gate_check: rustc_feature::Features::rustc_attrs,
notes: &[],
}unstable!(rustc_attrs);
107 const CREATE: fn(Span) -> AttributeKind =
108 |_| AttributeKind::RustcAllowLifetimeDependentSpecialization;
109 const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
110 note: "this attribute requires `unsafe` because lifetime constraints from \
111 the implementations of the trait are not considered when specializing",
112 unsafe_since: None,
113 };
114}
115
116pub(crate) struct RustcCoinductiveParser;
119impl NoArgsAttributeParser for RustcCoinductiveParser {
120 const PATH: &[Symbol] = &[sym::rustc_coinductive];
121 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
122 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
gate_check: rustc_feature::Features::rustc_attrs,
notes: &[],
}unstable!(rustc_attrs);
123 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive;
124}
125
126pub(crate) struct RustcAllowIncoherentImplParser;
127impl NoArgsAttributeParser for RustcAllowIncoherentImplParser {
128 const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
129 const ALLOWED_TARGETS: AllowedTargets<'_> =
130 AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
131 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
gate_check: rustc_feature::Features::rustc_attrs,
notes: &[],
}unstable!(rustc_attrs);
132 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl;
133}
134
135pub(crate) struct FundamentalParser;
136impl NoArgsAttributeParser for FundamentalParser {
137 const PATH: &[Symbol] = &[sym::fundamental];
138 const ALLOWED_TARGETS: AllowedTargets<'_> =
139 AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
140 const STABILITY: AttributeStability = AttributeStability::Unstable {
gate_name: rustc_span::sym::fundamental,
gate_check: rustc_feature::Features::fundamental,
notes: &[],
}unstable!(fundamental);
141 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
142}