]>
Commit | Line | Data |
---|---|---|
e1599b0c XL |
1 | //! Built-in attributes and `cfg` flag gating. |
2 | ||
e1599b0c | 3 | use AttributeGate::*; |
dfeec247 | 4 | use AttributeType::*; |
e1599b0c | 5 | |
60c5eb7d | 6 | use crate::{Features, Stability}; |
e1599b0c | 7 | |
dfeec247 XL |
8 | use rustc_data_structures::fx::FxHashMap; |
9 | use rustc_span::symbol::{sym, Symbol}; | |
e1599b0c | 10 | |
1b1a35ee XL |
11 | use std::lazy::SyncLazy; |
12 | ||
e1599b0c XL |
13 | type GateFn = fn(&Features) -> bool; |
14 | ||
15 | macro_rules! cfg_fn { | |
16 | ($field: ident) => { | |
dfeec247 XL |
17 | (|features| features.$field) as GateFn |
18 | }; | |
e1599b0c XL |
19 | } |
20 | ||
60c5eb7d XL |
21 | pub type GatedCfg = (Symbol, Symbol, GateFn); |
22 | ||
e1599b0c | 23 | /// `cfg(...)`'s that are feature gated. |
60c5eb7d | 24 | const GATED_CFGS: &[GatedCfg] = &[ |
e1599b0c | 25 | // (name in cfg, feature, function to check if the feature is enabled) |
136023e0 | 26 | (sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)), |
e1599b0c XL |
27 | (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), |
28 | (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), | |
e74abb32 | 29 | (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), |
1b1a35ee XL |
30 | ( |
31 | sym::target_has_atomic_equal_alignment, | |
32 | sym::cfg_target_has_atomic, | |
33 | cfg_fn!(cfg_target_has_atomic), | |
34 | ), | |
60c5eb7d | 35 | (sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)), |
f9f354fc | 36 | (sym::version, sym::cfg_version, cfg_fn!(cfg_version)), |
29967ef6 | 37 | (sym::panic, sym::cfg_panic, cfg_fn!(cfg_panic)), |
e1599b0c XL |
38 | ]; |
39 | ||
60c5eb7d XL |
40 | /// Find a gated cfg determined by the `pred`icate which is given the cfg's name. |
41 | pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg> { | |
42 | GATED_CFGS.iter().find(|(cfg_sym, ..)| pred(*cfg_sym)) | |
e1599b0c XL |
43 | } |
44 | ||
45 | // If you change this, please modify `src/doc/unstable-book` as well. You must | |
46 | // move that documentation into the relevant place in the other docs, and | |
47 | // remove the chapter on the flag. | |
48 | ||
49 | #[derive(Copy, Clone, PartialEq, Debug)] | |
50 | pub enum AttributeType { | |
51 | /// Normal, builtin attribute that is consumed | |
52 | /// by the compiler before the unused_attribute check | |
53 | Normal, | |
54 | ||
e1599b0c XL |
55 | /// Builtin attribute that is only allowed at the crate level |
56 | CrateLevel, | |
57 | } | |
58 | ||
59 | #[derive(Clone, Copy)] | |
60 | pub enum AttributeGate { | |
61 | /// Is gated by a given feature gate, reason | |
62 | /// and function to check if enabled | |
63 | Gated(Stability, Symbol, &'static str, fn(&Features) -> bool), | |
64 | ||
65 | /// Ungated attribute, can be used on all release channels | |
66 | Ungated, | |
67 | } | |
68 | ||
69 | // fn() is not Debug | |
70 | impl std::fmt::Debug for AttributeGate { | |
71 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
72 | match *self { | |
dfeec247 XL |
73 | Self::Gated(ref stab, name, expl, _) => { |
74 | write!(fmt, "Gated({:?}, {}, {})", stab, name, expl) | |
75 | } | |
76 | Self::Ungated => write!(fmt, "Ungated"), | |
e1599b0c XL |
77 | } |
78 | } | |
79 | } | |
80 | ||
81 | impl AttributeGate { | |
82 | fn is_deprecated(&self) -> bool { | |
29967ef6 | 83 | matches!(*self, Self::Gated(Stability::Deprecated(_, _), ..)) |
e1599b0c XL |
84 | } |
85 | } | |
86 | ||
60c5eb7d XL |
87 | /// A template that the attribute input must match. |
88 | /// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now. | |
ba9703b0 | 89 | #[derive(Clone, Copy, Default)] |
60c5eb7d XL |
90 | pub struct AttributeTemplate { |
91 | pub word: bool, | |
92 | pub list: Option<&'static str>, | |
93 | pub name_value_str: Option<&'static str>, | |
94 | } | |
95 | ||
e1599b0c XL |
96 | /// A convenience macro for constructing attribute templates. |
97 | /// E.g., `template!(Word, List: "description")` means that the attribute | |
98 | /// supports forms `#[attr]` and `#[attr(description)]`. | |
99 | macro_rules! template { | |
100 | (Word) => { template!(@ true, None, None) }; | |
101 | (List: $descr: expr) => { template!(@ false, Some($descr), None) }; | |
102 | (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) }; | |
103 | (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) }; | |
104 | (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) }; | |
105 | (List: $descr1: expr, NameValueStr: $descr2: expr) => { | |
106 | template!(@ false, Some($descr1), Some($descr2)) | |
107 | }; | |
108 | (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => { | |
109 | template!(@ true, Some($descr1), Some($descr2)) | |
110 | }; | |
111 | (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate { | |
112 | word: $word, list: $list, name_value_str: $name_value_str | |
113 | } }; | |
114 | } | |
115 | ||
116 | macro_rules! ungated { | |
117 | ($attr:ident, $typ:expr, $tpl:expr $(,)?) => { | |
118 | (sym::$attr, $typ, $tpl, Ungated) | |
119 | }; | |
120 | } | |
121 | ||
122 | macro_rules! gated { | |
123 | ($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => { | |
124 | (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate))) | |
125 | }; | |
126 | ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { | |
127 | (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr))) | |
128 | }; | |
129 | } | |
130 | ||
131 | macro_rules! rustc_attr { | |
132 | (TEST, $attr:ident, $typ:expr, $tpl:expr $(,)?) => { | |
133 | rustc_attr!( | |
dfeec247 XL |
134 | $attr, |
135 | $typ, | |
136 | $tpl, | |
137 | concat!( | |
138 | "the `#[", | |
139 | stringify!($attr), | |
140 | "]` attribute is just used for rustc unit tests \ | |
e1599b0c XL |
141 | and will never be stable", |
142 | ), | |
143 | ) | |
144 | }; | |
145 | ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { | |
dfeec247 XL |
146 | ( |
147 | sym::$attr, | |
148 | $typ, | |
149 | $tpl, | |
150 | Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), | |
151 | ) | |
e1599b0c XL |
152 | }; |
153 | } | |
154 | ||
155 | macro_rules! experimental { | |
156 | ($attr:ident) => { | |
157 | concat!("the `#[", stringify!($attr), "]` attribute is an experimental feature") | |
dfeec247 | 158 | }; |
e1599b0c XL |
159 | } |
160 | ||
161 | const IMPL_DETAIL: &str = "internal implementation detail"; | |
60c5eb7d | 162 | const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable"; |
e1599b0c XL |
163 | |
164 | pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate); | |
165 | ||
166 | /// Attributes that have a special meaning to rustc or rustdoc. | |
dfeec247 | 167 | #[rustfmt::skip] |
e1599b0c XL |
168 | pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ |
169 | // ========================================================================== | |
170 | // Stable attributes: | |
171 | // ========================================================================== | |
172 | ||
74b04a01 | 173 | // Conditional compilation: |
e1599b0c XL |
174 | ungated!(cfg, Normal, template!(List: "predicate")), |
175 | ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ...")), | |
176 | ||
177 | // Testing: | |
178 | ungated!(ignore, Normal, template!(Word, NameValueStr: "reason")), | |
179 | ungated!( | |
180 | should_panic, Normal, | |
181 | template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"), | |
182 | ), | |
183 | // FIXME(Centril): This can be used on stable but shouldn't. | |
94222f64 | 184 | ungated!(reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name")), |
e1599b0c XL |
185 | |
186 | // Macros: | |
e1599b0c XL |
187 | ungated!(automatically_derived, Normal, template!(Word)), |
188 | // FIXME(#14407) | |
189 | ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")), | |
190 | ungated!(macro_escape, Normal, template!(Word)), // Deprecated synonym for `macro_use`. | |
191 | ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")), | |
192 | ungated!(proc_macro, Normal, template!(Word)), | |
193 | ungated!( | |
194 | proc_macro_derive, Normal, | |
195 | template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"), | |
196 | ), | |
197 | ungated!(proc_macro_attribute, Normal, template!(Word)), | |
198 | ||
199 | // Lints: | |
200 | ungated!(warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), | |
201 | ungated!(allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), | |
202 | ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), | |
203 | ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), | |
94222f64 | 204 | ungated!(must_use, Normal, template!(Word, NameValueStr: "reason")), |
c295e0f8 XL |
205 | gated!( |
206 | must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), must_not_suspend, | |
207 | experimental!(must_not_suspend) | |
208 | ), | |
e1599b0c XL |
209 | // FIXME(#14407) |
210 | ungated!( | |
211 | deprecated, Normal, | |
212 | template!( | |
213 | Word, | |
214 | List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#, | |
215 | NameValueStr: "reason" | |
216 | ), | |
217 | ), | |
218 | ||
219 | // Crate properties: | |
220 | ungated!(crate_name, CrateLevel, template!(NameValueStr: "name")), | |
221 | ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|...")), | |
222 | ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored")), | |
223 | ||
224 | // ABI, linking, symbols, and FFI | |
225 | ungated!( | |
94222f64 | 226 | link, Normal, |
ba9703b0 | 227 | template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...""#), |
e1599b0c | 228 | ), |
94222f64 XL |
229 | ungated!(link_name, Normal, template!(NameValueStr: "name")), |
230 | ungated!(no_link, Normal, template!(Word)), | |
231 | ungated!(repr, Normal, template!(List: "C")), | |
232 | ungated!(export_name, Normal, template!(NameValueStr: "name")), | |
233 | ungated!(link_section, Normal, template!(NameValueStr: "name")), | |
234 | ungated!(no_mangle, Normal, template!(Word)), | |
235 | ungated!(used, Normal, template!(Word)), | |
e1599b0c XL |
236 | |
237 | // Limits: | |
238 | ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")), | |
239 | ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N")), | |
74b04a01 XL |
240 | gated!( |
241 | const_eval_limit, CrateLevel, template!(NameValueStr: "N"), const_eval_limit, | |
242 | experimental!(const_eval_limit) | |
243 | ), | |
cdc7bbd5 XL |
244 | gated!( |
245 | move_size_limit, CrateLevel, template!(NameValueStr: "N"), large_assignments, | |
246 | experimental!(move_size_limit) | |
247 | ), | |
e1599b0c XL |
248 | |
249 | // Entry point: | |
250 | ungated!(main, Normal, template!(Word)), | |
251 | ungated!(start, Normal, template!(Word)), | |
252 | ungated!(no_start, CrateLevel, template!(Word)), | |
253 | ungated!(no_main, CrateLevel, template!(Word)), | |
254 | ||
255 | // Modules, prelude, and resolution: | |
256 | ungated!(path, Normal, template!(NameValueStr: "file")), | |
257 | ungated!(no_std, CrateLevel, template!(Word)), | |
258 | ungated!(no_implicit_prelude, Normal, template!(Word)), | |
94222f64 | 259 | ungated!(non_exhaustive, Normal, template!(Word)), |
e1599b0c XL |
260 | |
261 | // Runtime | |
94222f64 | 262 | ungated!(windows_subsystem, Normal, template!(NameValueStr: "windows|console")), |
e1599b0c XL |
263 | ungated!(panic_handler, Normal, template!(Word)), // RFC 2070 |
264 | ||
265 | // Code generation: | |
94222f64 XL |
266 | ungated!(inline, Normal, template!(Word, List: "always|never")), |
267 | ungated!(cold, Normal, template!(Word)), | |
268 | ungated!(no_builtins, Normal, template!(Word)), | |
269 | ungated!(target_feature, Normal, template!(List: r#"enable = "name""#)), | |
270 | ungated!(track_caller, Normal, template!(Word)), | |
74b04a01 | 271 | gated!( |
94222f64 | 272 | no_sanitize, Normal, |
74b04a01 XL |
273 | template!(List: "address, memory, thread"), |
274 | experimental!(no_sanitize) | |
275 | ), | |
94222f64 | 276 | gated!(no_coverage, Normal, template!(Word), experimental!(no_coverage)), |
e1599b0c | 277 | |
f035d41b | 278 | // FIXME: #14408 assume docs are used since rustdoc looks at them. |
94222f64 | 279 | ungated!(doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string")), |
e1599b0c XL |
280 | |
281 | // ========================================================================== | |
282 | // Unstable attributes: | |
283 | // ========================================================================== | |
284 | ||
285 | // Linking: | |
94222f64 | 286 | gated!(naked, Normal, template!(Word), naked_functions, experimental!(naked)), |
e74abb32 | 287 | gated!( |
94222f64 | 288 | link_ordinal, Normal, template!(List: "ordinal"), raw_dylib, |
e74abb32 XL |
289 | experimental!(link_ordinal) |
290 | ), | |
e1599b0c XL |
291 | |
292 | // Plugins: | |
e74abb32 | 293 | ( |
60c5eb7d | 294 | sym::plugin, CrateLevel, template!(List: "name"), |
e74abb32 XL |
295 | Gated( |
296 | Stability::Deprecated( | |
297 | "https://github.com/rust-lang/rust/pull/64675", | |
298 | Some("may be removed in a future compiler version"), | |
299 | ), | |
300 | sym::plugin, | |
301 | "compiler plugins are deprecated", | |
302 | cfg_fn!(plugin) | |
303 | ) | |
e1599b0c XL |
304 | ), |
305 | ||
306 | // Testing: | |
307 | gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)), | |
308 | gated!( | |
309 | test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks, | |
310 | "custom test frameworks are an unstable feature", | |
311 | ), | |
e1599b0c | 312 | // RFC #1268 |
94222f64 | 313 | gated!(marker, Normal, template!(Word), marker_trait_attr, experimental!(marker)), |
e1599b0c | 314 | gated!( |
94222f64 | 315 | thread_local, Normal, template!(Word), |
e1599b0c XL |
316 | "`#[thread_local]` is an experimental feature, and does not currently handle destructors", |
317 | ), | |
318 | gated!(no_core, CrateLevel, template!(Word), experimental!(no_core)), | |
319 | // RFC 2412 | |
320 | gated!( | |
94222f64 | 321 | optimize, Normal, template!(List: "size|speed"), optimize_attribute, |
e1599b0c XL |
322 | experimental!(optimize), |
323 | ), | |
29967ef6 | 324 | // RFC 2867 |
94222f64 | 325 | gated!(instruction_set, Normal, template!(List: "set"), isa_attribute, experimental!(instruction_set)), |
e1599b0c | 326 | |
94222f64 XL |
327 | gated!(ffi_returns_twice, Normal, template!(Word), experimental!(ffi_returns_twice)), |
328 | gated!(ffi_pure, Normal, template!(Word), experimental!(ffi_pure)), | |
329 | gated!(ffi_const, Normal, template!(Word), experimental!(ffi_const)), | |
60c5eb7d XL |
330 | gated!( |
331 | register_attr, CrateLevel, template!(List: "attr1, attr2, ..."), | |
332 | experimental!(register_attr), | |
333 | ), | |
334 | gated!( | |
335 | register_tool, CrateLevel, template!(List: "tool1, tool2, ..."), | |
336 | experimental!(register_tool), | |
337 | ), | |
e1599b0c | 338 | |
94222f64 | 339 | gated!(cmse_nonsecure_entry, Normal, template!(Word), experimental!(cmse_nonsecure_entry)), |
136023e0 XL |
340 | // RFC 2632 |
341 | gated!( | |
94222f64 | 342 | default_method_body_is_const, Normal, template!(Word), const_trait_impl, |
136023e0 XL |
343 | "`default_method_body_is_const` is a temporary placeholder for declaring default bodies \ |
344 | as `const`, which may be removed or renamed in the future." | |
345 | ), | |
1b1a35ee | 346 | |
e1599b0c XL |
347 | // ========================================================================== |
348 | // Internal attributes: Stability, deprecation, and unsafe: | |
349 | // ========================================================================== | |
350 | ||
351 | ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")), | |
352 | // FIXME(#14407) -- only looked at on-demand so we can't | |
353 | // guarantee they'll have already been checked. | |
354 | ungated!( | |
94222f64 | 355 | rustc_deprecated, Normal, |
e1599b0c XL |
356 | template!(List: r#"since = "version", reason = "...""#) |
357 | ), | |
358 | // FIXME(#14407) | |
94222f64 | 359 | ungated!(stable, Normal, template!(List: r#"feature = "name", since = "version""#)), |
e1599b0c XL |
360 | // FIXME(#14407) |
361 | ungated!( | |
94222f64 | 362 | unstable, Normal, |
e1599b0c XL |
363 | template!(List: r#"feature = "name", reason = "...", issue = "N""#), |
364 | ), | |
60c5eb7d | 365 | // FIXME(#14407) |
94222f64 | 366 | ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#)), |
60c5eb7d | 367 | // FIXME(#14407) |
94222f64 | 368 | ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#)), |
e1599b0c | 369 | gated!( |
94222f64 | 370 | allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), |
60c5eb7d | 371 | "allow_internal_unstable side-steps feature gating and stability checks", |
e1599b0c | 372 | ), |
29967ef6 | 373 | gated!( |
94222f64 | 374 | rustc_allow_const_fn_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), |
29967ef6 XL |
375 | "rustc_allow_const_fn_unstable side-steps feature gating and stability checks" |
376 | ), | |
e1599b0c | 377 | gated!( |
60c5eb7d XL |
378 | allow_internal_unsafe, Normal, template!(Word), |
379 | "allow_internal_unsafe side-steps the unsafe_code lint", | |
e1599b0c | 380 | ), |
e1599b0c XL |
381 | |
382 | // ========================================================================== | |
383 | // Internal attributes: Type system related: | |
384 | // ========================================================================== | |
385 | ||
94222f64 | 386 | gated!(fundamental, Normal, template!(Word), experimental!(fundamental)), |
e1599b0c XL |
387 | gated!( |
388 | may_dangle, Normal, template!(Word), dropck_eyepatch, | |
389 | "`may_dangle` has unstable semantics and may be removed in the future", | |
390 | ), | |
391 | ||
392 | // ========================================================================== | |
393 | // Internal attributes: Runtime related: | |
394 | // ========================================================================== | |
395 | ||
94222f64 XL |
396 | rustc_attr!(rustc_allocator, Normal, template!(Word), IMPL_DETAIL), |
397 | rustc_attr!(rustc_allocator_nounwind, Normal, template!(Word), IMPL_DETAIL), | |
e1599b0c XL |
398 | gated!(alloc_error_handler, Normal, template!(Word), experimental!(alloc_error_handler)), |
399 | gated!( | |
94222f64 | 400 | default_lib_allocator, Normal, template!(Word), allocator_internals, |
e1599b0c XL |
401 | experimental!(default_lib_allocator), |
402 | ), | |
403 | gated!( | |
404 | needs_allocator, Normal, template!(Word), allocator_internals, | |
405 | experimental!(needs_allocator), | |
406 | ), | |
94222f64 XL |
407 | gated!(panic_runtime, Normal, template!(Word), experimental!(panic_runtime)), |
408 | gated!(needs_panic_runtime, Normal, template!(Word), experimental!(needs_panic_runtime)), | |
e1599b0c | 409 | gated!( |
94222f64 | 410 | compiler_builtins, Normal, template!(Word), |
e1599b0c XL |
411 | "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ |
412 | which contains compiler-rt intrinsics and will never be stable", | |
413 | ), | |
e1599b0c | 414 | gated!( |
94222f64 | 415 | profiler_runtime, Normal, template!(Word), |
e1599b0c XL |
416 | "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ |
417 | which contains the profiler runtime and will never be stable", | |
418 | ), | |
419 | ||
420 | // ========================================================================== | |
421 | // Internal attributes, Linkage: | |
422 | // ========================================================================== | |
423 | ||
424 | gated!( | |
94222f64 | 425 | linkage, Normal, template!(NameValueStr: "external|internal|..."), |
e1599b0c XL |
426 | "the `linkage` attribute is experimental and not portable across platforms", |
427 | ), | |
94222f64 | 428 | rustc_attr!(rustc_std_internal_symbol, Normal, template!(Word), INTERNAL_UNSTABLE), |
e1599b0c XL |
429 | |
430 | // ========================================================================== | |
431 | // Internal attributes, Macro related: | |
432 | // ========================================================================== | |
433 | ||
136023e0 | 434 | rustc_attr!( |
94222f64 | 435 | rustc_builtin_macro, Normal, |
136023e0 XL |
436 | template!(Word, List: "name, /*opt*/ attributes(name1, name2, ...)"), |
437 | IMPL_DETAIL, | |
438 | ), | |
60c5eb7d | 439 | rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE), |
e1599b0c | 440 | rustc_attr!( |
94222f64 | 441 | rustc_macro_transparency, Normal, |
e1599b0c XL |
442 | template!(NameValueStr: "transparent|semitransparent|opaque"), |
443 | "used internally for testing macro hygiene", | |
444 | ), | |
445 | ||
446 | // ========================================================================== | |
447 | // Internal attributes, Diagnostics related: | |
448 | // ========================================================================== | |
449 | ||
60c5eb7d | 450 | rustc_attr!( |
94222f64 | 451 | rustc_on_unimplemented, Normal, |
e1599b0c XL |
452 | template!( |
453 | List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#, | |
454 | NameValueStr: "message" | |
455 | ), | |
60c5eb7d | 456 | INTERNAL_UNSTABLE |
e1599b0c | 457 | ), |
f035d41b | 458 | // Enumerates "identity-like" conversion methods to suggest on type mismatch. |
94222f64 | 459 | rustc_attr!(rustc_conversion_suggestion, Normal, template!(Word), INTERNAL_UNSTABLE), |
c295e0f8 XL |
460 | // Prevents field reads in the marked trait or method to be considered |
461 | // during dead code analysis. | |
462 | rustc_attr!(rustc_trivial_field_reads, Normal, template!(Word), INTERNAL_UNSTABLE), | |
e1599b0c XL |
463 | |
464 | // ========================================================================== | |
465 | // Internal attributes, Const related: | |
466 | // ========================================================================== | |
467 | ||
94222f64 XL |
468 | rustc_attr!(rustc_promotable, Normal, template!(Word), IMPL_DETAIL), |
469 | rustc_attr!(rustc_legacy_const_generics, Normal, template!(List: "N"), INTERNAL_UNSTABLE), | |
c295e0f8 XL |
470 | // Do not const-check this function's body. It will always get replaced during CTFE. |
471 | rustc_attr!(rustc_do_not_const_check, Normal, template!(Word), INTERNAL_UNSTABLE), | |
e1599b0c XL |
472 | |
473 | // ========================================================================== | |
474 | // Internal attributes, Layout related: | |
475 | // ========================================================================== | |
476 | ||
477 | rustc_attr!( | |
94222f64 | 478 | rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), |
e1599b0c XL |
479 | "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ |
480 | niche optimizations in libcore and will never be stable", | |
481 | ), | |
482 | rustc_attr!( | |
94222f64 | 483 | rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), |
e1599b0c XL |
484 | "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ |
485 | niche optimizations in libcore and will never be stable", | |
486 | ), | |
487 | rustc_attr!( | |
94222f64 | 488 | rustc_nonnull_optimization_guaranteed, Normal, template!(Word), |
e1599b0c XL |
489 | "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \ |
490 | niche optimizations in libcore and will never be stable", | |
491 | ), | |
492 | ||
493 | // ========================================================================== | |
494 | // Internal attributes, Misc: | |
495 | // ========================================================================== | |
e1599b0c XL |
496 | gated!( |
497 | lang, Normal, template!(NameValueStr: "name"), lang_items, | |
498 | "language items are subject to change", | |
499 | ), | |
500 | ( | |
501 | sym::rustc_diagnostic_item, | |
502 | Normal, | |
503 | template!(NameValueStr: "name"), | |
504 | Gated( | |
505 | Stability::Unstable, | |
506 | sym::rustc_attrs, | |
507 | "diagnostic items compiler internal support for linting", | |
508 | cfg_fn!(rustc_attrs), | |
509 | ), | |
510 | ), | |
e1599b0c XL |
511 | gated!( |
512 | // Used in resolve: | |
94222f64 | 513 | prelude_import, Normal, template!(Word), |
e1599b0c XL |
514 | "`#[prelude_import]` is for use by rustc only", |
515 | ), | |
516 | gated!( | |
517 | rustc_paren_sugar, Normal, template!(Word), unboxed_closures, | |
518 | "unboxed_closures are still evolving", | |
519 | ), | |
520 | rustc_attr!( | |
94222f64 | 521 | rustc_inherit_overflow_checks, Normal, template!(Word), |
e1599b0c XL |
522 | "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ |
523 | overflow checking behavior of several libcore functions that are inlined \ | |
524 | across crates and will never be stable", | |
525 | ), | |
e74abb32 XL |
526 | rustc_attr!(rustc_reservation_impl, Normal, template!(NameValueStr: "reservation message"), |
527 | "the `#[rustc_reservation_impl]` attribute is internally used \ | |
528 | for reserving for `for<T> From<!> for T` impl" | |
529 | ), | |
e1599b0c XL |
530 | rustc_attr!( |
531 | rustc_test_marker, Normal, template!(Word), | |
532 | "the `#[rustc_test_marker]` attribute is used internally to track tests", | |
533 | ), | |
ba9703b0 XL |
534 | rustc_attr!( |
535 | rustc_unsafe_specialization_marker, Normal, template!(Word), | |
536 | "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations" | |
537 | ), | |
538 | rustc_attr!( | |
539 | rustc_specialization_trait, Normal, template!(Word), | |
540 | "the `#[rustc_specialization_trait]` attribute is used to check specializations" | |
541 | ), | |
cdc7bbd5 XL |
542 | rustc_attr!( |
543 | rustc_main, Normal, template!(Word), | |
544 | "the `#[rustc_main]` attribute is used internally to specify test entry point function", | |
545 | ), | |
546 | rustc_attr!( | |
547 | rustc_skip_array_during_method_dispatch, Normal, template!(Word), | |
548 | "the `#[rustc_skip_array_during_method_dispatch]` attribute is used to exclude a trait \ | |
549 | from method dispatch when the receiver is an array, for compatibility in editions < 2021." | |
550 | ), | |
e1599b0c XL |
551 | |
552 | // ========================================================================== | |
553 | // Internal attributes, Testing: | |
554 | // ========================================================================== | |
555 | ||
556 | rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)), | |
fc512014 | 557 | rustc_attr!(TEST, rustc_capture_analysis, Normal, template!(Word)), |
17df50a5 | 558 | rustc_attr!(TEST, rustc_insignificant_dtor, Normal, template!(Word)), |
e1599b0c XL |
559 | rustc_attr!(TEST, rustc_variance, Normal, template!(Word)), |
560 | rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")), | |
561 | rustc_attr!(TEST, rustc_regions, Normal, template!(Word)), | |
60c5eb7d | 562 | rustc_attr!( |
94222f64 | 563 | TEST, rustc_error, Normal, |
60c5eb7d XL |
564 | template!(Word, List: "delay_span_bug_from_inside_query") |
565 | ), | |
94222f64 XL |
566 | rustc_attr!(TEST, rustc_dump_user_substs, Normal, template!(Word)), |
567 | rustc_attr!(TEST, rustc_evaluate_where_clauses, Normal, template!(Word)), | |
568 | rustc_attr!(TEST, rustc_if_this_changed, Normal, template!(Word, List: "DepNode")), | |
569 | rustc_attr!(TEST, rustc_then_this_would_need, Normal, template!(List: "DepNode")), | |
e1599b0c | 570 | rustc_attr!( |
94222f64 | 571 | TEST, rustc_clean, Normal, |
e1599b0c XL |
572 | template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), |
573 | ), | |
574 | rustc_attr!( | |
94222f64 | 575 | TEST, rustc_partition_reused, Normal, |
e1599b0c XL |
576 | template!(List: r#"cfg = "...", module = "...""#), |
577 | ), | |
578 | rustc_attr!( | |
94222f64 | 579 | TEST, rustc_partition_codegened, Normal, |
e1599b0c XL |
580 | template!(List: r#"cfg = "...", module = "...""#), |
581 | ), | |
582 | rustc_attr!( | |
94222f64 | 583 | TEST, rustc_expected_cgu_reuse, Normal, |
e1599b0c XL |
584 | template!(List: r#"cfg = "...", module = "...", kind = "...""#), |
585 | ), | |
94222f64 XL |
586 | rustc_attr!(TEST, rustc_synthetic, Normal, template!(Word)), |
587 | rustc_attr!(TEST, rustc_symbol_name, Normal, template!(Word)), | |
588 | rustc_attr!(TEST, rustc_polymorphize_error, Normal, template!(Word)), | |
589 | rustc_attr!(TEST, rustc_def_path, Normal, template!(Word)), | |
590 | rustc_attr!(TEST, rustc_mir, Normal, template!(List: "arg1, arg2, ...")), | |
591 | rustc_attr!(TEST, rustc_dump_program_clauses, Normal, template!(Word)), | |
592 | rustc_attr!(TEST, rustc_dump_env_program_clauses, Normal, template!(Word)), | |
593 | rustc_attr!(TEST, rustc_object_lifetime_default, Normal, template!(Word)), | |
594 | rustc_attr!(TEST, rustc_dump_vtable, Normal, template!(Word)), | |
e1599b0c XL |
595 | rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/)), |
596 | gated!( | |
94222f64 | 597 | omit_gdb_pretty_printer_section, Normal, template!(Word), |
e1599b0c XL |
598 | "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite", |
599 | ), | |
600 | ]; | |
601 | ||
602 | pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> { | |
603 | BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect() | |
604 | } | |
605 | ||
60c5eb7d | 606 | pub fn is_builtin_attr_name(name: Symbol) -> bool { |
e1599b0c XL |
607 | BUILTIN_ATTRIBUTE_MAP.get(&name).is_some() |
608 | } | |
609 | ||
29967ef6 | 610 | pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy<FxHashMap<Symbol, &BuiltinAttribute>> = |
1b1a35ee | 611 | SyncLazy::new(|| { |
e1599b0c XL |
612 | let mut map = FxHashMap::default(); |
613 | for attr in BUILTIN_ATTRIBUTES.iter() { | |
614 | if map.insert(attr.0, attr).is_some() { | |
615 | panic!("duplicate builtin attribute `{}`", attr.0); | |
616 | } | |
617 | } | |
618 | map | |
1b1a35ee | 619 | }); |