rustc_attr_parsing/attributes/
crate_level.rs1use 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}