Skip to main content

rustc_attr_parsing/attributes/
traits.rs

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