Skip to main content

rustc_attr_parsing/attributes/
traits.rs

1use 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 {
46            array,
47            boxed_slice,
48            span: cx.attr_span,
49        })
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 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 CREATE: fn(Span) -> AttributeKind = AttributeKind::Marker;
72}
73
74pub(crate) struct RustcDenyExplicitImplParser;
75impl NoArgsAttributeParser for RustcDenyExplicitImplParser {
76    const PATH: &[Symbol] = &[sym::rustc_deny_explicit_impl];
77    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
78    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDenyExplicitImpl;
79}
80
81pub(crate) struct RustcDynIncompatibleTraitParser;
82impl NoArgsAttributeParser for RustcDynIncompatibleTraitParser {
83    const PATH: &[Symbol] = &[sym::rustc_dyn_incompatible_trait];
84    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
85    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDynIncompatibleTrait;
86}
87
88// Specialization
89
90pub(crate) struct RustcSpecializationTraitParser;
91impl NoArgsAttributeParser for RustcSpecializationTraitParser {
92    const PATH: &[Symbol] = &[sym::rustc_specialization_trait];
93    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
94    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcSpecializationTrait;
95}
96
97pub(crate) struct RustcUnsafeSpecializationMarkerParser;
98impl NoArgsAttributeParser for RustcUnsafeSpecializationMarkerParser {
99    const PATH: &[Symbol] = &[sym::rustc_unsafe_specialization_marker];
100    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
101    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcUnsafeSpecializationMarker;
102}
103
104// Coherence
105
106pub(crate) struct RustcCoinductiveParser;
107impl NoArgsAttributeParser for RustcCoinductiveParser {
108    const PATH: &[Symbol] = &[sym::rustc_coinductive];
109    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
110    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoinductive;
111}
112
113pub(crate) struct RustcAllowIncoherentImplParser;
114impl NoArgsAttributeParser for RustcAllowIncoherentImplParser {
115    const PATH: &[Symbol] = &[sym::rustc_allow_incoherent_impl];
116    const ALLOWED_TARGETS: AllowedTargets =
117        AllowedTargets::AllowList(&[Allow(Target::Method(MethodKind::Inherent))]);
118    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcAllowIncoherentImpl;
119}
120
121pub(crate) struct FundamentalParser;
122impl NoArgsAttributeParser for FundamentalParser {
123    const PATH: &[Symbol] = &[sym::fundamental];
124    const ALLOWED_TARGETS: AllowedTargets =
125        AllowedTargets::AllowList(&[Allow(Target::Struct), Allow(Target::Trait)]);
126    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Fundamental;
127}