rustc_attr_parsing/attributes/
crate_level.rs

1use rustc_hir::attrs::WindowsSubsystemKind;
2
3use super::prelude::*;
4
5pub(crate) struct CrateNameParser;
6
7impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
8    const PATH: &[Symbol] = &[sym::crate_name];
9    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
10    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
11    const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
12    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
13
14    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
15        let ArgParser::NameValue(n) = args else {
16            cx.expected_name_value(cx.attr_span, None);
17            return None;
18        };
19
20        let Some(name) = n.value_as_str() else {
21            cx.expected_string_literal(n.value_span, Some(n.value_as_lit()));
22            return None;
23        };
24
25        Some(AttributeKind::CrateName { name, name_span: n.value_span, attr_span: cx.attr_span })
26    }
27}
28
29pub(crate) struct RecursionLimitParser;
30
31impl<S: Stage> SingleAttributeParser<S> for RecursionLimitParser {
32    const PATH: &[Symbol] = &[sym::recursion_limit];
33    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
34    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
35    const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute");
36    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
37
38    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
39        let ArgParser::NameValue(nv) = args else {
40            cx.expected_name_value(cx.attr_span, None);
41            return None;
42        };
43
44        Some(AttributeKind::RecursionLimit {
45            limit: cx.parse_limit_int(nv)?,
46            attr_span: cx.attr_span,
47            limit_span: nv.value_span,
48        })
49    }
50}
51
52pub(crate) struct MoveSizeLimitParser;
53
54impl<S: Stage> SingleAttributeParser<S> for MoveSizeLimitParser {
55    const PATH: &[Symbol] = &[sym::move_size_limit];
56    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
57    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
58    const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
59    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
60
61    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
62        let ArgParser::NameValue(nv) = args else {
63            cx.expected_name_value(cx.attr_span, None);
64            return None;
65        };
66
67        Some(AttributeKind::MoveSizeLimit {
68            limit: cx.parse_limit_int(nv)?,
69            attr_span: cx.attr_span,
70            limit_span: nv.value_span,
71        })
72    }
73}
74
75pub(crate) struct TypeLengthLimitParser;
76
77impl<S: Stage> SingleAttributeParser<S> for TypeLengthLimitParser {
78    const PATH: &[Symbol] = &[sym::type_length_limit];
79    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
80    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
81    const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
82    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
83
84    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
85        let ArgParser::NameValue(nv) = args else {
86            cx.expected_name_value(cx.attr_span, None);
87            return None;
88        };
89
90        Some(AttributeKind::TypeLengthLimit {
91            limit: cx.parse_limit_int(nv)?,
92            attr_span: cx.attr_span,
93            limit_span: nv.value_span,
94        })
95    }
96}
97
98pub(crate) struct PatternComplexityLimitParser;
99
100impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
101    const PATH: &[Symbol] = &[sym::pattern_complexity_limit];
102    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
103    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
104    const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
105    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
106
107    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
108        let ArgParser::NameValue(nv) = args else {
109            cx.expected_name_value(cx.attr_span, None);
110            return None;
111        };
112
113        Some(AttributeKind::PatternComplexityLimit {
114            limit: cx.parse_limit_int(nv)?,
115            attr_span: cx.attr_span,
116            limit_span: nv.value_span,
117        })
118    }
119}
120
121pub(crate) struct NoCoreParser;
122
123impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser {
124    const PATH: &[Symbol] = &[sym::no_core];
125    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
126    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
127    const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore;
128}
129
130pub(crate) struct NoStdParser;
131
132impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
133    const PATH: &[Symbol] = &[sym::no_std];
134    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
135    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
136    const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
137}
138
139pub(crate) struct RustcCoherenceIsCoreParser;
140
141impl<S: Stage> NoArgsAttributeParser<S> for RustcCoherenceIsCoreParser {
142    const PATH: &[Symbol] = &[sym::rustc_coherence_is_core];
143    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
144    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
145    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoherenceIsCore;
146}
147
148pub(crate) struct WindowsSubsystemParser;
149
150impl<S: Stage> SingleAttributeParser<S> for WindowsSubsystemParser {
151    const PATH: &[Symbol] = &[sym::windows_subsystem];
152    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
153    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
154    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
155    const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute");
156
157    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
158        let Some(nv) = args.name_value() else {
159            cx.expected_name_value(
160                args.span().unwrap_or(cx.inner_span),
161                Some(sym::windows_subsystem),
162            );
163            return None;
164        };
165
166        let kind = match nv.value_as_str() {
167            Some(sym::console) => WindowsSubsystemKind::Console,
168            Some(sym::windows) => WindowsSubsystemKind::Windows,
169            Some(_) | None => {
170                cx.expected_specific_argument_strings(nv.value_span, &[sym::console, sym::windows]);
171                return None;
172            }
173        };
174
175        Some(AttributeKind::WindowsSubsystem(kind, cx.attr_span))
176    }
177}