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;
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 = {
_ = rustc_feature::Features::rustc_attrs;
AttributeStability::Unstable {
gate_name: rustc_span::sym::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 = {
_ = rustc_feature::Features::unboxed_closures;
AttributeStability::Unstable {
gate_name: rustc_span::sym::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(&[Allow(Target::Trait)]);
67 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::marker_trait_attr;
AttributeStability::Unstable {
gate_name: rustc_span::sym::marker_trait_attr,
notes: &[],
}
}unstable!(marker_trait_attr);
68 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Marker;
69}
70
71pub(crate) struct RustcDenyExplicitImplParser;
72impl NoArgsAttributeParser for RustcDenyExplicitImplParser {
73 const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
74 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
75 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::rustc_attrs;
AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
notes: &[],
}
}unstable!(rustc_attrs);
76 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDenyExplicitImpl;
77}
78
79pub(crate) struct RustcDynIncompatibleTraitParser;
80impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser {
81 const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
82 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
83 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::rustc_attrs;
AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
notes: &[],
}
}unstable!(rustc_attrs);
84 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait;
85}
86
87pub(crate) struct RustcSpecializationTraitParser;
90impl NoArgsAttributeParser for RustcSpecializationTraitParser {
91 const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
92 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
93 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::rustc_attrs;
AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
notes: &[],
}
}unstable!(rustc_attrs);
94 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcSpecializationTrait;
95}
96
97pub(crate) struct RustcAllowLifetimeDependentSpecializationParser;
98impl NoArgsAttributeParser for RustcAllowLifetimeDependentSpecializationParser {
99 const PATH: &[Symbol] = &[sym::rustc_allow_lifetime_dependent_specialization];
100 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
101 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::rustc_attrs;
AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
notes: &[],
}
}unstable!(rustc_attrs);
102 const CREATE: fn(Span) -> AttributeKind =
103 |_| AttributeKind::RustcAllowLifetimeDependentSpecialization;
104 const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
105 note: "this attribute requires `unsafe` because lifetime constraints from \
106 the implementations of the trait are not considered when specializing",
107 unsafe_since: None,
108 };
109}
110
111pub(crate) struct RustcCoinductiveParser;
114impl NoArgsAttributeParser for RustcCoinductiveParser {
115 const PATH: &[Symbol] = &[sym::rustc_coinductive];
116 const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
117 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::rustc_attrs;
AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
notes: &[],
}
}unstable!(rustc_attrs);
118 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcCoinductive;
119}
120
121pub(crate) struct RustcAllowIncoherentImplParser;
122impl NoArgsAttributeParser for RustcAllowIncoherentImplParser {
123 const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
124 const ALLOWED_TARGETS: AllowedTargets<'_> =
125 AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
126 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::rustc_attrs;
AttributeStability::Unstable {
gate_name: rustc_span::sym::rustc_attrs,
notes: &[],
}
}unstable!(rustc_attrs);
127 const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl;
128}
129
130pub(crate) struct FundamentalParser;
131impl NoArgsAttributeParser for FundamentalParser {
132 const PATH: &[Symbol] = &[sym::fundamental];
133 const ALLOWED_TARGETS: AllowedTargets<'_> =
134 AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
135 const STABILITY: AttributeStability = {
_ = rustc_feature::Features::fundamental;
AttributeStability::Unstable {
gate_name: rustc_span::sym::fundamental,
notes: &[],
}
}unstable!(fundamental);
136 const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
137}