Skip to main content

rustc_attr_parsing/attributes/
allow_unstable.rs

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