Skip to main content

rustc_attr_parsing/attributes/
traits.rs

1use 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
61// Markers
62
63pub(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
92// Specialization
93
94pub(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
116// Coherence
117
118pub(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}