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;
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
61// Markers
62
63pub(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
87// Specialization
88
89pub(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
111// Coherence
112
113pub(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}