Skip to main content

rustc_attr_parsing/attributes/
allow_unstable.rs

1use std::iter;
2
3use rustc_feature::AttributeStability;
4
5use super::prelude::*;
6use crate::session_diagnostics;
7
8pub(crate) struct AllowInternalUnstableParser;
9impl CombineAttributeParser for AllowInternalUnstableParser {
10    const PATH: &[Symbol] = &[sym::allow_internal_unstable];
11    type Item = (Symbol, Span);
12    const CONVERT: ConvertFn<Self::Item> =
13        |items, span| AttributeKind::AllowInternalUnstable(items, span);
14    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
15        Allow(Target::MacroDef),
16        Allow(Target::Fn),
17        Warn(Target::Field),
18        Warn(Target::Arm),
19    ]);
20    const TEMPLATE: AttributeTemplate = crate::AttributeTemplate {
    word: true,
    list: Some(&["feat1, feat2, ..."]),
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word, List: &["feat1, feat2, ..."]);
21    const STABILITY: AttributeStability = AttributeStability::Unstable {
    gate_name: rustc_span::sym::allow_internal_unstable,
    gate_check: rustc_feature::Features::allow_internal_unstable,
    notes: &[],
}unstable!(allow_internal_unstable);
22
23    fn extend(
24        cx: &mut AcceptContext<'_, '_>,
25        args: &ArgParser,
26    ) -> impl IntoIterator<Item = Self::Item> {
27        parse_unstable(cx, args, <Self as CombineAttributeParser>::PATH[0])
28            .into_iter()
29            .zip(iter::repeat(cx.attr_span))
30    }
31}
32
33pub(crate) struct UnstableFeatureBoundParser;
34impl CombineAttributeParser for UnstableFeatureBoundParser {
35    const PATH: &[rustc_span::Symbol] = &[sym::unstable_feature_bound];
36    type Item = (Symbol, Span);
37    const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::UnstableFeatureBound(items);
38    const STABILITY: AttributeStability = AttributeStability::Unstable {
    gate_name: rustc_span::sym::staged_api,
    gate_check: rustc_feature::Features::staged_api,
    notes: &[],
}unstable!(staged_api);
39    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
40        Allow(Target::Fn),
41        Allow(Target::Impl { of_trait: true }),
42        Allow(Target::Trait),
43    ]);
44    const TEMPLATE: AttributeTemplate = crate::AttributeTemplate {
    word: true,
    list: Some(&["feat1, feat2, ..."]),
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word, List: &["feat1, feat2, ..."]);
45
46    fn extend(
47        cx: &mut AcceptContext<'_, '_>,
48        args: &ArgParser,
49    ) -> impl IntoIterator<Item = Self::Item> {
50        parse_unstable(cx, args, <Self as CombineAttributeParser>::PATH[0])
51            .into_iter()
52            .zip(iter::repeat(cx.attr_span))
53    }
54}
55
56pub(crate) struct RustcAllowConstFnUnstableParser;
57impl CombineAttributeParser for RustcAllowConstFnUnstableParser {
58    const PATH: &[Symbol] = &[sym::rustc_allow_const_fn_unstable];
59    type Item = Symbol;
60    const CONVERT: ConvertFn<Self::Item> =
61        |items, first_span| AttributeKind::RustcAllowConstFnUnstable(items, first_span);
62    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
63        Allow(Target::Fn),
64        Allow(Target::Method(MethodKind::Inherent)),
65        Allow(Target::Method(MethodKind::Trait { body: true })),
66        Allow(Target::Method(MethodKind::TraitImpl)),
67    ]);
68    const TEMPLATE: AttributeTemplate = crate::AttributeTemplate {
    word: true,
    list: Some(&["feat1, feat2, ..."]),
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word, List: &["feat1, feat2, ..."]);
69    const STABILITY: AttributeStability = AttributeStability::Unstable {
    gate_name: rustc_span::sym::rustc_attrs,
    gate_check: rustc_feature::Features::rustc_attrs,
    notes: &["rustc_allow_const_fn_unstable side-steps feature gating and stability checks"],
}unstable!(
70        rustc_attrs,
71        "rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
72    );
73
74    fn extend(
75        cx: &mut AcceptContext<'_, '_>,
76        args: &ArgParser,
77    ) -> impl IntoIterator<Item = Self::Item> {
78        parse_unstable(cx, args, <Self as CombineAttributeParser>::PATH[0])
79    }
80}
81
82fn parse_unstable(
83    cx: &AcceptContext<'_, '_>,
84    args: &ArgParser,
85    symbol: Symbol,
86) -> impl IntoIterator<Item = Symbol> {
87    let mut res = Vec::new();
88
89    let Some(list) = args.as_list() else {
90        cx.emit_err(session_diagnostics::ExpectsFeatureList {
91            span: cx.attr_span,
92            name: symbol.to_ident_string(),
93        });
94        return res;
95    };
96
97    for param in list.mixed() {
98        let param_span = param.span();
99        if let Some(ident) = param.meta_item_no_args().and_then(|i| i.path().word()) {
100            res.push(ident.name);
101        } else {
102            cx.emit_err(session_diagnostics::ExpectsFeatures {
103                span: param_span,
104                name: symbol.to_ident_string(),
105            });
106        }
107    }
108
109    res
110}