1use std::sync::LazyLock;
4
5use AttributeDuplicates::*;
6use AttributeGate::*;
7use AttributeType::*;
8use rustc_data_structures::fx::FxHashMap;
9use rustc_hir::attrs::EncodeCrossCrate;
10use rustc_span::edition::Edition;
11use rustc_span::{Symbol, sym};
12
13use crate::Features;
14
15type GateFn = fn(&Features) -> bool;
16
17pub type GatedCfg = (Symbol, Symbol, GateFn);
18
19const GATED_CFGS: &[GatedCfg] = &[
21 (sym::overflow_checks, sym::cfg_overflow_checks, Features::cfg_overflow_checks),
23 (sym::ub_checks, sym::cfg_ub_checks, Features::cfg_ub_checks),
24 (sym::contract_checks, sym::cfg_contract_checks, Features::cfg_contract_checks),
25 (sym::target_thread_local, sym::cfg_target_thread_local, Features::cfg_target_thread_local),
26 (
27 sym::target_has_atomic_equal_alignment,
28 sym::cfg_target_has_atomic_equal_alignment,
29 Features::cfg_target_has_atomic_equal_alignment,
30 ),
31 (
32 sym::target_has_atomic_load_store,
33 sym::cfg_target_has_atomic,
34 Features::cfg_target_has_atomic,
35 ),
36 (sym::sanitize, sym::cfg_sanitize, Features::cfg_sanitize),
37 (sym::version, sym::cfg_version, Features::cfg_version),
38 (sym::relocation_model, sym::cfg_relocation_model, Features::cfg_relocation_model),
39 (sym::sanitizer_cfi_generalize_pointers, sym::cfg_sanitizer_cfi, Features::cfg_sanitizer_cfi),
40 (sym::sanitizer_cfi_normalize_integers, sym::cfg_sanitizer_cfi, Features::cfg_sanitizer_cfi),
41 (sym::fmt_debug, sym::fmt_debug, Features::fmt_debug),
43 (sym::emscripten_wasm_eh, sym::cfg_emscripten_wasm_eh, Features::cfg_emscripten_wasm_eh),
44 (
45 sym::target_has_reliable_f16,
46 sym::cfg_target_has_reliable_f16_f128,
47 Features::cfg_target_has_reliable_f16_f128,
48 ),
49 (
50 sym::target_has_reliable_f16_math,
51 sym::cfg_target_has_reliable_f16_f128,
52 Features::cfg_target_has_reliable_f16_f128,
53 ),
54 (
55 sym::target_has_reliable_f128,
56 sym::cfg_target_has_reliable_f16_f128,
57 Features::cfg_target_has_reliable_f16_f128,
58 ),
59 (
60 sym::target_has_reliable_f128_math,
61 sym::cfg_target_has_reliable_f16_f128,
62 Features::cfg_target_has_reliable_f16_f128,
63 ),
64];
65
66pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg> {
68 GATED_CFGS.iter().find(|(cfg_sym, ..)| pred(*cfg_sym))
69}
70
71#[derive(Copy, Clone, PartialEq, Debug)]
76pub enum AttributeType {
77 Normal,
80
81 CrateLevel,
83}
84
85#[derive(Copy, Clone, PartialEq, Debug)]
86pub enum AttributeSafety {
87 Normal,
89
90 Unsafe { unsafe_since: Option<Edition> },
96}
97
98#[derive(Clone, Debug, Copy)]
99pub enum AttributeGate {
100 Gated {
102 feature: Symbol,
104 message: &'static str,
106 check: fn(&Features) -> bool,
108 notes: &'static [&'static str],
110 },
111 Ungated,
113}
114
115#[derive(Clone, Copy, Default)]
119pub struct AttributeTemplate {
120 pub word: bool,
122 pub list: Option<&'static [&'static str]>,
124 pub one_of: &'static [Symbol],
127 pub name_value_str: Option<&'static [&'static str]>,
130 pub docs: Option<&'static str>,
132}
133
134impl AttributeTemplate {
135 pub fn suggestions(&self, inner: bool, name: impl std::fmt::Display) -> Vec<String> {
136 let mut suggestions = vec![];
137 let inner = if inner { "!" } else { "" };
138 if self.word {
139 suggestions.push(format!("#{inner}[{name}]"));
140 }
141 if let Some(descr) = self.list {
142 for descr in descr {
143 suggestions.push(format!("#{inner}[{name}({descr})]"));
144 }
145 }
146 suggestions.extend(self.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]")));
147 if let Some(descr) = self.name_value_str {
148 for descr in descr {
149 suggestions.push(format!("#{inner}[{name} = \"{descr}\"]"));
150 }
151 }
152 suggestions.sort();
153
154 suggestions
155 }
156}
157
158#[derive(Clone, Copy, Default)]
160pub enum AttributeDuplicates {
161 #[default]
168 DuplicatesOk,
169 WarnFollowing,
175 WarnFollowingWordOnly,
181 ErrorFollowing,
187 ErrorPreceding,
193 FutureWarnFollowing,
200 FutureWarnPreceding,
207}
208
209#[macro_export]
213macro_rules! template {
214 (Word) => { $crate::template!(@ true, None, &[], None, None) };
215 (Word, $link: literal) => { $crate::template!(@ true, None, &[], None, Some($link)) };
216 (List: $descr: expr) => { $crate::template!(@ false, Some($descr), &[], None, None) };
217 (List: $descr: expr, $link: literal) => { $crate::template!(@ false, Some($descr), &[], None, Some($link)) };
218 (OneOf: $one_of: expr) => { $crate::template!(@ false, None, $one_of, None, None) };
219 (NameValueStr: [$($descr: literal),* $(,)?]) => { $crate::template!(@ false, None, &[], Some(&[$($descr,)*]), None) };
220 (NameValueStr: [$($descr: literal),* $(,)?], $link: literal) => { $crate::template!(@ false, None, &[], Some(&[$($descr,)*]), Some($link)) };
221 (NameValueStr: $descr: literal) => { $crate::template!(@ false, None, &[], Some(&[$descr]), None) };
222 (NameValueStr: $descr: literal, $link: literal) => { $crate::template!(@ false, None, &[], Some(&[$descr]), Some($link)) };
223 (Word, List: $descr: expr) => { $crate::template!(@ true, Some($descr), &[], None, None) };
224 (Word, List: $descr: expr, $link: literal) => { $crate::template!(@ true, Some($descr), &[], None, Some($link)) };
225 (Word, NameValueStr: $descr: expr) => { $crate::template!(@ true, None, &[], Some(&[$descr]), None) };
226 (Word, NameValueStr: $descr: expr, $link: literal) => { $crate::template!(@ true, None, &[], Some(&[$descr]), Some($link)) };
227 (List: $descr1: expr, NameValueStr: $descr2: expr) => {
228 $crate::template!(@ false, Some($descr1), &[], Some(&[$descr2]), None)
229 };
230 (List: $descr1: expr, NameValueStr: $descr2: expr, $link: literal) => {
231 $crate::template!(@ false, Some($descr1), &[], Some(&[$descr2]), Some($link))
232 };
233 (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
234 $crate::template!(@ true, Some($descr1), &[], Some(&[$descr2]), None)
235 };
236 (Word, List: $descr1: expr, NameValueStr: $descr2: expr, $link: literal) => {
237 $crate::template!(@ true, Some($descr1), &[], Some(&[$descr2]), Some($link))
238 };
239 (@ $word: expr, $list: expr, $one_of: expr, $name_value_str: expr, $link: expr) => { $crate::AttributeTemplate {
240 word: $word, list: $list, one_of: $one_of, name_value_str: $name_value_str, docs: $link,
241 } };
242}
243
244macro_rules! ungated {
245 (unsafe($edition:ident) $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
246 BuiltinAttribute {
247 name: sym::$attr,
248 encode_cross_crate: $encode_cross_crate,
249 type_: $typ,
250 safety: AttributeSafety::Unsafe { unsafe_since: Some(Edition::$edition) },
251 template: $tpl,
252 gate: Ungated,
253 duplicates: $duplicates,
254 }
255 };
256 (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
257 BuiltinAttribute {
258 name: sym::$attr,
259 encode_cross_crate: $encode_cross_crate,
260 type_: $typ,
261 safety: AttributeSafety::Unsafe { unsafe_since: None },
262 template: $tpl,
263 gate: Ungated,
264 duplicates: $duplicates,
265 }
266 };
267 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
268 BuiltinAttribute {
269 name: sym::$attr,
270 encode_cross_crate: $encode_cross_crate,
271 type_: $typ,
272 safety: AttributeSafety::Normal,
273 template: $tpl,
274 gate: Ungated,
275 duplicates: $duplicates,
276 }
277 };
278}
279
280macro_rules! gated {
281 (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => {
282 BuiltinAttribute {
283 name: sym::$attr,
284 encode_cross_crate: $encode_cross_crate,
285 type_: $typ,
286 safety: AttributeSafety::Unsafe { unsafe_since: None },
287 template: $tpl,
288 duplicates: $duplicates,
289 gate: Gated {
290 feature: sym::$gate,
291 message: $message,
292 check: Features::$gate,
293 notes: &[],
294 },
295 }
296 };
297 (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => {
298 BuiltinAttribute {
299 name: sym::$attr,
300 encode_cross_crate: $encode_cross_crate,
301 type_: $typ,
302 safety: AttributeSafety::Unsafe { unsafe_since: None },
303 template: $tpl,
304 duplicates: $duplicates,
305 gate: Gated {
306 feature: sym::$attr,
307 message: $message,
308 check: Features::$attr,
309 notes: &[],
310 },
311 }
312 };
313 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => {
314 BuiltinAttribute {
315 name: sym::$attr,
316 encode_cross_crate: $encode_cross_crate,
317 type_: $typ,
318 safety: AttributeSafety::Normal,
319 template: $tpl,
320 duplicates: $duplicates,
321 gate: Gated {
322 feature: sym::$gate,
323 message: $message,
324 check: Features::$gate,
325 notes: &[],
326 },
327 }
328 };
329 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => {
330 BuiltinAttribute {
331 name: sym::$attr,
332 encode_cross_crate: $encode_cross_crate,
333 type_: $typ,
334 safety: AttributeSafety::Normal,
335 template: $tpl,
336 duplicates: $duplicates,
337 gate: Gated {
338 feature: sym::$attr,
339 message: $message,
340 check: Features::$attr,
341 notes: &[],
342 },
343 }
344 };
345}
346
347macro_rules! rustc_attr {
348 (TEST, $attr:ident, $typ:expr, $tpl:expr, $duplicate:expr, $encode_cross_crate:expr $(,)?) => {
349 rustc_attr!(
350 $attr,
351 $typ,
352 $tpl,
353 $duplicate,
354 $encode_cross_crate,
355 concat!(
356 "the `#[",
357 stringify!($attr),
358 "]` attribute is used for rustc unit tests"
359 ),
360 )
361 };
362 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $($notes:expr),* $(,)?) => {
363 BuiltinAttribute {
364 name: sym::$attr,
365 encode_cross_crate: $encode_cross_crate,
366 type_: $typ,
367 safety: AttributeSafety::Normal,
368 template: $tpl,
369 duplicates: $duplicates,
370 gate: Gated {
371 feature: sym::rustc_attrs,
372 message: "use of an internal attribute",
373 check: Features::rustc_attrs,
374 notes: &[
375 concat!("the `#[",
376 stringify!($attr),
377 "]` attribute is an internal implementation detail that will never be stable"),
378 $($notes),*
379 ]
380 },
381 }
382 };
383}
384
385macro_rules! experimental {
386 ($attr:ident) => {
387 concat!("the `#[", stringify!($attr), "]` attribute is an experimental feature")
388 };
389}
390
391pub struct BuiltinAttribute {
392 pub name: Symbol,
393 pub encode_cross_crate: EncodeCrossCrate,
398 pub type_: AttributeType,
399 pub safety: AttributeSafety,
400 pub template: AttributeTemplate,
401 pub duplicates: AttributeDuplicates,
402 pub gate: AttributeGate,
403}
404
405#[rustfmt::skip]
407pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
408 ungated!(
414 cfg, Normal,
415 template!(
416 List: &["predicate"],
417 "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute"
418 ),
419 DuplicatesOk, EncodeCrossCrate::Yes
420 ),
421 ungated!(
422 cfg_attr, Normal,
423 template!(
424 List: &["predicate, attr1, attr2, ..."],
425 "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute"
426 ),
427 DuplicatesOk, EncodeCrossCrate::Yes
428 ),
429
430 ungated!(
432 ignore, Normal,
433 template!(
434 Word,
435 NameValueStr: "reason",
436 "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute"
437 ),
438 WarnFollowing, EncodeCrossCrate::No,
439 ),
440 ungated!(
441 should_panic, Normal,
442 template!(
443 Word,
444 List: &[r#"expected = "reason""#],
445 NameValueStr: "reason",
446 "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute"
447 ),
448 FutureWarnFollowing, EncodeCrossCrate::No,
449 ),
450 ungated!(
452 reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing,
453 EncodeCrossCrate::No,
454 ),
455
456 ungated!(
458 automatically_derived, Normal,
459 template!(
460 Word,
461 "https://doc.rust-lang.org/reference/attributes/derive.html#the-automatically_derived-attribute"
462 ),
463 WarnFollowing, EncodeCrossCrate::Yes
464 ),
465 ungated!(
466 macro_use, Normal,
467 template!(
468 Word,
469 List: &["name1, name2, ..."],
470 "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute"
471 ),
472 WarnFollowingWordOnly, EncodeCrossCrate::No,
473 ),
474 ungated!(macro_escape, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), ungated!(
476 macro_export, Normal,
477 template!(
478 Word,
479 List: &["local_inner_macros"],
480 "https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope"
481 ),
482 WarnFollowing, EncodeCrossCrate::Yes
483 ),
484 ungated!(
485 proc_macro, Normal,
486 template!(
487 Word,
488 "https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros"),
489 ErrorFollowing, EncodeCrossCrate::No
490 ),
491 ungated!(
492 proc_macro_derive, Normal,
493 template!(
494 List: &["TraitName", "TraitName, attributes(name1, name2, ...)"],
495 "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros"
496 ),
497 ErrorFollowing, EncodeCrossCrate::No,
498 ),
499 ungated!(
500 proc_macro_attribute, Normal,
501 template!(Word, "https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros"),
502 ErrorFollowing, EncodeCrossCrate::No
503 ),
504
505 ungated!(
507 warn, Normal,
508 template!(
509 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
510 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
511 ),
512 DuplicatesOk, EncodeCrossCrate::No,
513 ),
514 ungated!(
515 allow, Normal,
516 template!(
517 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
518 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
519 ),
520 DuplicatesOk, EncodeCrossCrate::No,
521 ),
522 ungated!(
523 expect, Normal,
524 template!(
525 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
526 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
527 ),
528 DuplicatesOk, EncodeCrossCrate::No,
529 ),
530 ungated!(
531 forbid, Normal,
532 template!(
533 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
534 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
535 ),
536 DuplicatesOk, EncodeCrossCrate::No
537 ),
538 ungated!(
539 deny, Normal,
540 template!(
541 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
542 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
543 ),
544 DuplicatesOk, EncodeCrossCrate::No
545 ),
546 ungated!(
547 must_use, Normal,
548 template!(
549 Word,
550 NameValueStr: "reason",
551 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"
552 ),
553 FutureWarnFollowing, EncodeCrossCrate::Yes
554 ),
555 gated!(
556 must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
557 EncodeCrossCrate::Yes, experimental!(must_not_suspend)
558 ),
559 ungated!(
560 deprecated, Normal,
561 template!(
562 Word,
563 List: &[r#"/*opt*/ since = "version", /*opt*/ note = "reason""#],
564 NameValueStr: "reason",
565 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute"
566 ),
567 ErrorFollowing, EncodeCrossCrate::Yes
568 ),
569
570 ungated!(
572 crate_name, CrateLevel,
573 template!(
574 NameValueStr: "name",
575 "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute"
576 ),
577 FutureWarnFollowing, EncodeCrossCrate::No,
578 ),
579 ungated!(
580 crate_type, CrateLevel,
581 template!(
582 NameValueStr: ["bin", "lib", "dylib", "cdylib", "rlib", "staticlib", "sdylib", "proc-macro"],
583 "https://doc.rust-lang.org/reference/linkage.html"
584 ),
585 DuplicatesOk, EncodeCrossCrate::No,
586 ),
587
588 ungated!(
590 link, Normal,
591 template!(List: &[
592 r#"name = "...""#,
593 r#"name = "...", kind = "dylib|static|...""#,
594 r#"name = "...", wasm_import_module = "...""#,
595 r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#,
596 r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#,
597 ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"),
598 DuplicatesOk, EncodeCrossCrate::No,
599 ),
600 ungated!(
601 link_name, Normal,
602 template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute"),
603 FutureWarnPreceding, EncodeCrossCrate::Yes
604 ),
605 ungated!(
606 no_link, Normal,
607 template!(Word, "https://doc.rust-lang.org/reference/items/extern-crates.html#the-no_link-attribute"),
608 WarnFollowing, EncodeCrossCrate::No
609 ),
610 ungated!(
611 repr, Normal,
612 template!(
613 List: &["C", "Rust", "transparent", "align(...)", "packed(...)", "<integer type>"],
614 "https://doc.rust-lang.org/reference/type-layout.html#representations"
615 ),
616 DuplicatesOk, EncodeCrossCrate::No
617 ),
618 gated!(rustc_align, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
620 ungated!(
621 unsafe(Edition2024) export_name, Normal,
622 template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"),
623 FutureWarnPreceding, EncodeCrossCrate::No
624 ),
625 ungated!(
626 unsafe(Edition2024) link_section, Normal,
627 template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute"),
628 FutureWarnPreceding, EncodeCrossCrate::No
629 ),
630 ungated!(
631 unsafe(Edition2024) no_mangle, Normal,
632 template!(Word, "https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute"),
633 WarnFollowing, EncodeCrossCrate::No
634 ),
635 ungated!(
636 used, Normal,
637 template!(Word, List: &["compiler", "linker"], "https://doc.rust-lang.org/reference/abi.html#the-used-attribute"),
638 WarnFollowing, EncodeCrossCrate::No
639 ),
640 ungated!(
641 link_ordinal, Normal,
642 template!(List: &["ordinal"], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute"),
643 ErrorPreceding, EncodeCrossCrate::Yes
644 ),
645 ungated!(
646 unsafe naked, Normal,
647 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-naked-attribute"),
648 WarnFollowing, EncodeCrossCrate::No
649 ),
650
651 ungated!(
653 recursion_limit, CrateLevel,
654 template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"),
655 FutureWarnFollowing, EncodeCrossCrate::No
656 ),
657 ungated!(
658 type_length_limit, CrateLevel,
659 template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-type_length_limit-attribute"),
660 FutureWarnFollowing, EncodeCrossCrate::No
661 ),
662 gated!(
663 move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
664 EncodeCrossCrate::No, large_assignments, experimental!(move_size_limit)
665 ),
666
667 ungated!(
669 no_main, CrateLevel,
670 template!(Word, "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-no_main-attribute"),
671 WarnFollowing, EncodeCrossCrate::No
672 ),
673
674 ungated!(
676 path, Normal,
677 template!(NameValueStr: "file", "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute"),
678 FutureWarnFollowing, EncodeCrossCrate::No
679 ),
680 ungated!(
681 no_std, CrateLevel,
682 template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute"),
683 WarnFollowing, EncodeCrossCrate::No
684 ),
685 ungated!(
686 no_implicit_prelude, Normal,
687 template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_implicit_prelude-attribute"),
688 WarnFollowing, EncodeCrossCrate::No
689 ),
690 ungated!(
691 non_exhaustive, Normal,
692 template!(Word, "https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute"),
693 WarnFollowing, EncodeCrossCrate::Yes
694 ),
695
696 ungated!(
698 windows_subsystem, CrateLevel,
699 template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"),
700 FutureWarnFollowing, EncodeCrossCrate::No
701 ),
702 ungated!( panic_handler, Normal,
704 template!(Word, "https://doc.rust-lang.org/reference/panic.html#the-panic_handler-attribute"),
705 WarnFollowing, EncodeCrossCrate::Yes
706 ),
707
708 ungated!(
710 inline, Normal,
711 template!(
712 Word,
713 List: &["always", "never"],
714 "https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute"
715 ),
716 FutureWarnFollowing, EncodeCrossCrate::No
717 ),
718 ungated!(
719 cold, Normal,
720 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-cold-attribute"),
721 WarnFollowing, EncodeCrossCrate::No
722 ),
723 ungated!(
724 no_builtins, CrateLevel,
725 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-no_builtins-attribute"),
726 WarnFollowing, EncodeCrossCrate::Yes
727 ),
728 ungated!(
729 target_feature, Normal,
730 template!(List: &[r#"enable = "name""#], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute"),
731 DuplicatesOk, EncodeCrossCrate::No,
732 ),
733 ungated!(
734 track_caller, Normal,
735 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-track_caller-attribute"),
736 WarnFollowing, EncodeCrossCrate::Yes
737 ),
738 ungated!(
739 instruction_set, Normal,
740 template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"),
741 ErrorPreceding, EncodeCrossCrate::No
742 ),
743 gated!(
744 no_sanitize, Normal,
745 template!(List: &["address, kcfi, memory, thread"]), DuplicatesOk,
746 EncodeCrossCrate::No, experimental!(no_sanitize)
747 ),
748 gated!(
749 coverage, Normal, template!(OneOf: &[sym::off, sym::on]),
750 ErrorPreceding, EncodeCrossCrate::No,
751 coverage_attribute, experimental!(coverage)
752 ),
753
754 ungated!(
755 doc, Normal,
756 template!(
757 List: &["hidden", "inline"],
758 NameValueStr: "string",
759 "https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html"
760 ),
761 DuplicatesOk, EncodeCrossCrate::Yes
762 ),
763
764 ungated!(
766 debugger_visualizer, Normal,
767 template!(
768 List: &[r#"natvis_file = "...", gdb_script_file = "...""#],
769 "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute"
770 ),
771 DuplicatesOk, EncodeCrossCrate::No
772 ),
773 ungated!(
774 collapse_debuginfo, Normal,
775 template!(
776 List: &["no", "external", "yes"],
777 "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
778 ),
779 ErrorFollowing, EncodeCrossCrate::Yes
780 ),
781
782 gated!(
788 export_stable, Normal, template!(Word), WarnFollowing,
789 EncodeCrossCrate::No, experimental!(export_stable)
790 ),
791
792 gated!(
794 test_runner, CrateLevel, template!(List: &["path"]), ErrorFollowing,
795 EncodeCrossCrate::Yes, custom_test_frameworks,
796 "custom test frameworks are an unstable feature",
797 ),
798 gated!(
800 marker, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
801 marker_trait_attr, experimental!(marker)
802 ),
803 gated!(
804 thread_local, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
805 "`#[thread_local]` is an experimental feature, and does not currently handle destructors",
806 ),
807 gated!(
808 no_core, CrateLevel, template!(Word), WarnFollowing,
809 EncodeCrossCrate::No, experimental!(no_core)
810 ),
811 gated!(
813 optimize, Normal, template!(List: &["none", "size", "speed"]), ErrorPreceding,
814 EncodeCrossCrate::No, optimize_attribute, experimental!(optimize)
815 ),
816
817 gated!(
818 unsafe ffi_pure, Normal, template!(Word), WarnFollowing,
819 EncodeCrossCrate::No, experimental!(ffi_pure)
820 ),
821 gated!(
822 unsafe ffi_const, Normal, template!(Word), WarnFollowing,
823 EncodeCrossCrate::No, experimental!(ffi_const)
824 ),
825 gated!(
826 register_tool, CrateLevel, template!(List: &["tool1, tool2, ..."]), DuplicatesOk,
827 EncodeCrossCrate::No, experimental!(register_tool),
828 ),
829
830 gated!(
833 const_trait, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No, const_trait_impl,
834 "`const_trait` is a temporary placeholder for marking a trait that is suitable for `const` \
835 `impls` and all default bodies as `const`, which may be removed or renamed in the \
836 future."
837 ),
838 gated!(
840 deprecated_safe, Normal, template!(List: &[r#"since = "version", note = "...""#]), ErrorFollowing,
841 EncodeCrossCrate::Yes, experimental!(deprecated_safe),
842 ),
843
844 gated!(
846 cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding,
847 EncodeCrossCrate::Yes, experimental!(cfi_encoding)
848 ),
849
850 gated!(
852 coroutine, Normal, template!(Word), ErrorFollowing,
853 EncodeCrossCrate::No, coroutines, experimental!(coroutine)
854 ),
855
856 gated!(
859 patchable_function_entry, Normal, template!(List: &["prefix_nops = m, entry_nops = n"]), ErrorPreceding,
860 EncodeCrossCrate::Yes, experimental!(patchable_function_entry)
861 ),
862
863 gated!(
866 type_const, Normal, template!(Word), ErrorFollowing,
867 EncodeCrossCrate::Yes, min_generic_const_args, experimental!(type_const),
868 ),
869
870 gated!(
875 const_continue, Normal, template!(Word), ErrorFollowing,
876 EncodeCrossCrate::No, loop_match, experimental!(const_continue)
877 ),
878 gated!(
879 loop_match, Normal, template!(Word), ErrorFollowing,
880 EncodeCrossCrate::No, loop_match, experimental!(loop_match)
881 ),
882
883 ungated!(
888 feature, CrateLevel,
889 template!(List: &["name1, name2, ..."]), DuplicatesOk, EncodeCrossCrate::No,
890 ),
891 ungated!(
893 stable, Normal,
894 template!(List: &[r#"feature = "name", since = "version""#]), DuplicatesOk, EncodeCrossCrate::No,
895 ),
896 ungated!(
897 unstable, Normal,
898 template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]), DuplicatesOk,
899 EncodeCrossCrate::Yes
900 ),
901 ungated!(
902 unstable_feature_bound, Normal, template!(Word, List: &["feat1, feat2, ..."]),
903 DuplicatesOk, EncodeCrossCrate::No,
904 ),
905 ungated!(
906 rustc_const_unstable, Normal, template!(List: &[r#"feature = "name""#]),
907 DuplicatesOk, EncodeCrossCrate::Yes
908 ),
909 ungated!(
910 rustc_const_stable, Normal,
911 template!(List: &[r#"feature = "name""#]), DuplicatesOk, EncodeCrossCrate::No,
912 ),
913 ungated!(
914 rustc_default_body_unstable, Normal,
915 template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]),
916 DuplicatesOk, EncodeCrossCrate::No
917 ),
918 gated!(
919 allow_internal_unstable, Normal, template!(Word, List: &["feat1, feat2, ..."]),
920 DuplicatesOk, EncodeCrossCrate::Yes,
921 "allow_internal_unstable side-steps feature gating and stability checks",
922 ),
923 gated!(
924 allow_internal_unsafe, Normal, template!(Word), WarnFollowing,
925 EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
926 ),
927 rustc_attr!(
928 rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"),
929 WarnFollowing, EncodeCrossCrate::No,
930 "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
931 through unstable paths"
932 ),
933 rustc_attr!(
934 rustc_deprecated_safe_2024, Normal, template!(List: &[r#"audit_that = "...""#]),
935 ErrorFollowing, EncodeCrossCrate::Yes,
936 "`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary",
937 ),
938 rustc_attr!(
939 rustc_pub_transparent, Normal, template!(Word),
940 ErrorFollowing, EncodeCrossCrate::Yes,
941 "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
942 ),
943
944
945 gated!(fundamental, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, experimental!(fundamental)),
950 gated!(
951 may_dangle, Normal, template!(Word), WarnFollowing,
952 EncodeCrossCrate::No, dropck_eyepatch,
953 "`may_dangle` has unstable semantics and may be removed in the future",
954 ),
955
956 rustc_attr!(
957 rustc_never_type_options,
958 Normal,
959 template!(List: &[
960 "",
961 r#"fallback = "unit""#,
962 r#"fallback = "niko""#,
963 r#"fallback = "never""#,
964 r#"fallback = "no""#,
965 ]),
966 ErrorFollowing,
967 EncodeCrossCrate::No,
968 "`rustc_never_type_options` is used to experiment with never type fallback and work on \
969 never type stabilization"
970 ),
971
972 rustc_attr!(
977 rustc_allocator, Normal, template!(Word), WarnFollowing,
978 EncodeCrossCrate::No,
979 ),
980 rustc_attr!(
981 rustc_nounwind, Normal, template!(Word), WarnFollowing,
982 EncodeCrossCrate::No,
983 ),
984 rustc_attr!(
985 rustc_reallocator, Normal, template!(Word), WarnFollowing,
986 EncodeCrossCrate::No,
987 ),
988 rustc_attr!(
989 rustc_deallocator, Normal, template!(Word), WarnFollowing,
990 EncodeCrossCrate::No,
991 ),
992 rustc_attr!(
993 rustc_allocator_zeroed, Normal, template!(Word), WarnFollowing,
994 EncodeCrossCrate::No,
995 ),
996 gated!(
997 default_lib_allocator, Normal, template!(Word), WarnFollowing,
998 EncodeCrossCrate::No, allocator_internals, experimental!(default_lib_allocator),
999 ),
1000 gated!(
1001 needs_allocator, Normal, template!(Word), WarnFollowing,
1002 EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator),
1003 ),
1004 gated!(
1005 panic_runtime, CrateLevel, template!(Word), WarnFollowing,
1006 EncodeCrossCrate::No, experimental!(panic_runtime)
1007 ),
1008 gated!(
1009 needs_panic_runtime, CrateLevel, template!(Word), WarnFollowing,
1010 EncodeCrossCrate::No, experimental!(needs_panic_runtime)
1011 ),
1012 gated!(
1013 compiler_builtins, CrateLevel, template!(Word), WarnFollowing,
1014 EncodeCrossCrate::No,
1015 "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
1016 which contains compiler-rt intrinsics and will never be stable",
1017 ),
1018 gated!(
1019 profiler_runtime, CrateLevel, template!(Word), WarnFollowing,
1020 EncodeCrossCrate::No,
1021 "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
1022 which contains the profiler runtime and will never be stable",
1023 ),
1024
1025 gated!(
1030 linkage, Normal, template!(NameValueStr: [
1031 "available_externally",
1032 "common",
1033 "extern_weak",
1034 "external",
1035 "internal",
1036 "linkonce",
1037 "linkonce_odr",
1038 "weak",
1039 "weak_odr",
1040 ], "https://doc.rust-lang.org/reference/linkage.html"),
1041 ErrorPreceding, EncodeCrossCrate::No,
1042 "the `linkage` attribute is experimental and not portable across platforms",
1043 ),
1044 rustc_attr!(
1045 rustc_std_internal_symbol, Normal, template!(Word), WarnFollowing,
1046 EncodeCrossCrate::No,
1047 ),
1048
1049 rustc_attr!(
1054 rustc_builtin_macro, Normal,
1055 template!(Word, List: &["name", "name, /*opt*/ attributes(name1, name2, ...)"]), ErrorFollowing,
1056 EncodeCrossCrate::Yes,
1057 ),
1058 rustc_attr!(
1059 rustc_proc_macro_decls, Normal, template!(Word), WarnFollowing,
1060 EncodeCrossCrate::No,
1061 ),
1062 rustc_attr!(
1063 rustc_macro_transparency, Normal,
1064 template!(NameValueStr: ["transparent", "semiopaque", "opaque"]), ErrorFollowing,
1065 EncodeCrossCrate::Yes, "used internally for testing macro hygiene",
1066 ),
1067 rustc_attr!(
1068 rustc_autodiff, Normal,
1069 template!(Word, List: &[r#""...""#]), DuplicatesOk,
1070 EncodeCrossCrate::Yes,
1071 ),
1072 ungated!(
1077 cfg_trace, Normal, template!(Word ), DuplicatesOk,
1078 EncodeCrossCrate::No
1079 ),
1080 ungated!(
1081 cfg_attr_trace, Normal, template!(Word ), DuplicatesOk,
1082 EncodeCrossCrate::No
1083 ),
1084
1085 rustc_attr!(
1090 rustc_on_unimplemented, Normal,
1091 template!(
1092 List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#],
1093 NameValueStr: "message"
1094 ),
1095 ErrorFollowing, EncodeCrossCrate::Yes,
1096 "see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute"
1097 ),
1098 rustc_attr!(
1099 rustc_confusables, Normal,
1100 template!(List: &[r#""name1", "name2", ..."#]),
1101 ErrorFollowing, EncodeCrossCrate::Yes,
1102 ),
1103 rustc_attr!(
1105 rustc_conversion_suggestion, Normal, template!(Word),
1106 WarnFollowing, EncodeCrossCrate::Yes,
1107 ),
1108 rustc_attr!(
1111 rustc_trivial_field_reads, Normal, template!(Word),
1112 WarnFollowing, EncodeCrossCrate::Yes,
1113 ),
1114 rustc_attr!(
1117 rustc_lint_query_instability, Normal, template!(Word),
1118 WarnFollowing, EncodeCrossCrate::Yes,
1119 ),
1120 rustc_attr!(
1123 rustc_lint_untracked_query_information, Normal, template!(Word),
1124 WarnFollowing, EncodeCrossCrate::Yes,
1125 ),
1126 rustc_attr!(
1129 rustc_lint_diagnostics, Normal, template!(Word),
1130 WarnFollowing, EncodeCrossCrate::Yes,
1131 ),
1132 rustc_attr!(
1135 rustc_lint_opt_ty, Normal, template!(Word),
1136 WarnFollowing, EncodeCrossCrate::Yes,
1137 ),
1138 rustc_attr!(
1141 rustc_lint_opt_deny_field_access, Normal, template!(List: &["message"]),
1142 WarnFollowing, EncodeCrossCrate::Yes,
1143 ),
1144
1145 rustc_attr!(
1150 rustc_promotable, Normal, template!(Word), WarnFollowing,
1151 EncodeCrossCrate::No, ),
1152 rustc_attr!(
1153 rustc_legacy_const_generics, Normal, template!(List: &["N"]), ErrorFollowing,
1154 EncodeCrossCrate::Yes,
1155 ),
1156 rustc_attr!(
1158 rustc_do_not_const_check, Normal, template!(Word), WarnFollowing,
1159 EncodeCrossCrate::Yes, "`#[rustc_do_not_const_check]` skips const-check for this function's body",
1160 ),
1161 rustc_attr!(
1162 rustc_const_panic_str, Normal, template!(Word), WarnFollowing,
1163 EncodeCrossCrate::Yes, "`#[rustc_const_panic_str]` ensures the argument to this function is &&str during const-check",
1164 ),
1165 rustc_attr!(
1166 rustc_const_stable_indirect, Normal,
1167 template!(Word),
1168 WarnFollowing,
1169 EncodeCrossCrate::No,
1170 "this is an internal implementation detail",
1171 ),
1172 rustc_attr!(
1173 rustc_intrinsic_const_stable_indirect, Normal,
1174 template!(Word), WarnFollowing, EncodeCrossCrate::No, "this is an internal implementation detail",
1175 ),
1176 gated!(
1177 rustc_allow_const_fn_unstable, Normal,
1178 template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No,
1179 "rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
1180 ),
1181
1182 rustc_attr!(
1187 rustc_layout_scalar_valid_range_start, Normal, template!(List: &["value"]), ErrorFollowing,
1188 EncodeCrossCrate::Yes,
1189 "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
1190 niche optimizations in the standard library",
1191 ),
1192 rustc_attr!(
1193 rustc_layout_scalar_valid_range_end, Normal, template!(List: &["value"]), ErrorFollowing,
1194 EncodeCrossCrate::Yes,
1195 "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
1196 niche optimizations in the standard library",
1197 ),
1198 rustc_attr!(
1199 rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
1200 EncodeCrossCrate::Yes,
1201 "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \
1202 guaranteed niche optimizations in the standard library",
1203 "the compiler does not even check whether the type indeed is being non-null-optimized; \
1204 it is your responsibility to ensure that the attribute is only used on types that are optimized",
1205 ),
1206
1207 gated!(
1211 lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, EncodeCrossCrate::No, lang_items,
1212 "lang items are subject to change",
1213 ),
1214 rustc_attr!(
1215 rustc_as_ptr, Normal, template!(Word), ErrorFollowing,
1216 EncodeCrossCrate::Yes,
1217 "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations."
1218 ),
1219 rustc_attr!(
1220 rustc_pass_by_value, Normal, template!(Word), ErrorFollowing,
1221 EncodeCrossCrate::Yes,
1222 "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference."
1223 ),
1224 rustc_attr!(
1225 rustc_never_returns_null_ptr, Normal, template!(Word), ErrorFollowing,
1226 EncodeCrossCrate::Yes,
1227 "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers."
1228 ),
1229 rustc_attr!(
1230 rustc_no_implicit_autorefs, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
1231 "`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument."
1232 ),
1233 rustc_attr!(
1234 rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
1235 "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`."
1236 ),
1237 rustc_attr!(
1238 rustc_coinductive, AttributeType::Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
1239 "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver."
1240 ),
1241 rustc_attr!(
1242 rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
1243 "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl."
1244 ),
1245 rustc_attr!(
1246 rustc_preserve_ub_checks, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
1247 "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR",
1248 ),
1249 rustc_attr!(
1250 rustc_deny_explicit_impl,
1251 AttributeType::Normal,
1252 template!(Word),
1253 ErrorFollowing,
1254 EncodeCrossCrate::No,
1255 "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls"
1256 ),
1257 rustc_attr!(
1258 rustc_do_not_implement_via_object,
1259 AttributeType::Normal,
1260 template!(Word),
1261 ErrorFollowing,
1262 EncodeCrossCrate::No,
1263 "`#[rustc_do_not_implement_via_object]` opts out of the automatic trait impl for trait objects \
1264 (`impl Trait for dyn Trait`)"
1265 ),
1266 rustc_attr!(
1267 rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word),
1268 ErrorFollowing, EncodeCrossCrate::Yes,
1269 "`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \
1270 the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`."
1271 ),
1272
1273 BuiltinAttribute {
1274 name: sym::rustc_diagnostic_item,
1275 encode_cross_crate: EncodeCrossCrate::Yes,
1277 type_: Normal,
1278 safety: AttributeSafety::Normal,
1279 template: template!(NameValueStr: "name"),
1280 duplicates: ErrorFollowing,
1281 gate: Gated{
1282 feature: sym::rustc_attrs,
1283 message: "use of an internal attribute",
1284 check: Features::rustc_attrs,
1285 notes: &["the `#[rustc_diagnostic_item]` attribute allows the compiler to reference types \
1286 from the standard library for diagnostic purposes"],
1287 },
1288 },
1289 gated!(
1290 prelude_import, Normal, template!(Word), WarnFollowing,
1292 EncodeCrossCrate::No, "`#[prelude_import]` is for use by rustc only",
1293 ),
1294 gated!(
1295 rustc_paren_sugar, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
1296 unboxed_closures, "unboxed_closures are still evolving",
1297 ),
1298 rustc_attr!(
1299 rustc_inherit_overflow_checks, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
1300 "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
1301 overflow checking behavior of several functions in the standard library that are inlined \
1302 across crates",
1303 ),
1304 rustc_attr!(
1305 rustc_reservation_impl, Normal,
1306 template!(NameValueStr: "reservation message"), ErrorFollowing, EncodeCrossCrate::Yes,
1307 "the `#[rustc_reservation_impl]` attribute is internally used \
1308 for reserving `impl<T> From<!> for T` as part of the effort to stabilize `!`"
1309 ),
1310 rustc_attr!(
1311 rustc_test_marker, Normal, template!(NameValueStr: "name"), WarnFollowing,
1312 EncodeCrossCrate::No, "the `#[rustc_test_marker]` attribute is used internally to track tests",
1313 ),
1314 rustc_attr!(
1315 rustc_unsafe_specialization_marker, Normal, template!(Word),
1316 WarnFollowing, EncodeCrossCrate::No,
1317 "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations"
1318 ),
1319 rustc_attr!(
1320 rustc_specialization_trait, Normal, template!(Word),
1321 WarnFollowing, EncodeCrossCrate::No,
1322 "the `#[rustc_specialization_trait]` attribute is used to check specializations"
1323 ),
1324 rustc_attr!(
1325 rustc_main, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
1326 "the `#[rustc_main]` attribute is used internally to specify test entry point function",
1327 ),
1328 rustc_attr!(
1329 rustc_skip_during_method_dispatch, Normal, template!(List: &["array, boxed_slice"]), ErrorFollowing,
1330 EncodeCrossCrate::No,
1331 "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \
1332 from method dispatch when the receiver is of the following type, for compatibility in \
1333 editions < 2021 (array) or editions < 2024 (boxed_slice)."
1334 ),
1335 rustc_attr!(
1336 rustc_must_implement_one_of, Normal, template!(List: &["function1, function2, ..."]),
1337 ErrorFollowing, EncodeCrossCrate::No,
1338 "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \
1339 definition of a trait. Its syntax and semantics are highly experimental and will be \
1340 subject to change before stabilization",
1341 ),
1342 rustc_attr!(
1343 rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
1344 EncodeCrossCrate::Yes, "the `#[rustc_doc_primitive]` attribute is used by the standard library \
1345 to provide a way to generate documentation for primitive types",
1346 ),
1347 gated!(
1348 rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
1349 "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",
1350 ),
1351 rustc_attr!(
1352 rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
1353 "`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen"
1354 ),
1355 rustc_attr!(
1356 rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes,
1357 "`#[rustc_force_inline]` forces a free function to be inlined"
1358 ),
1359
1360 rustc_attr!(TEST, rustc_effective_visibility, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
1365 rustc_attr!(
1366 TEST, rustc_outlives, Normal, template!(Word),
1367 WarnFollowing, EncodeCrossCrate::No
1368 ),
1369 rustc_attr!(
1370 TEST, rustc_capture_analysis, Normal, template!(Word),
1371 WarnFollowing, EncodeCrossCrate::No
1372 ),
1373 rustc_attr!(
1374 TEST, rustc_insignificant_dtor, Normal, template!(Word),
1375 WarnFollowing, EncodeCrossCrate::Yes
1376 ),
1377 rustc_attr!(
1378 TEST, rustc_no_implicit_bounds, CrateLevel, template!(Word),
1379 WarnFollowing, EncodeCrossCrate::No
1380 ),
1381 rustc_attr!(
1382 TEST, rustc_strict_coherence, Normal, template!(Word),
1383 WarnFollowing, EncodeCrossCrate::Yes
1384 ),
1385 rustc_attr!(
1386 TEST, rustc_variance, Normal, template!(Word),
1387 WarnFollowing, EncodeCrossCrate::No
1388 ),
1389 rustc_attr!(
1390 TEST, rustc_variance_of_opaques, Normal, template!(Word),
1391 WarnFollowing, EncodeCrossCrate::No
1392 ),
1393 rustc_attr!(
1394 TEST, rustc_hidden_type_of_opaques, Normal, template!(Word),
1395 WarnFollowing, EncodeCrossCrate::No
1396 ),
1397 rustc_attr!(
1398 TEST, rustc_layout, Normal, template!(List: &["field1, field2, ..."]),
1399 WarnFollowing, EncodeCrossCrate::Yes
1400 ),
1401 rustc_attr!(
1402 TEST, rustc_abi, Normal, template!(List: &["field1, field2, ..."]),
1403 WarnFollowing, EncodeCrossCrate::No
1404 ),
1405 rustc_attr!(
1406 TEST, rustc_regions, Normal, template!(Word),
1407 WarnFollowing, EncodeCrossCrate::No
1408 ),
1409 rustc_attr!(
1410 TEST, rustc_delayed_bug_from_inside_query, Normal,
1411 template!(Word),
1412 WarnFollowing, EncodeCrossCrate::No
1413 ),
1414 rustc_attr!(
1415 TEST, rustc_dump_user_args, Normal, template!(Word),
1416 WarnFollowing, EncodeCrossCrate::No
1417 ),
1418 rustc_attr!(
1419 TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing,
1420 EncodeCrossCrate::Yes
1421 ),
1422 rustc_attr!(
1423 TEST, rustc_if_this_changed, Normal, template!(Word, List: &["DepNode"]), DuplicatesOk,
1424 EncodeCrossCrate::No
1425 ),
1426 rustc_attr!(
1427 TEST, rustc_then_this_would_need, Normal, template!(List: &["DepNode"]), DuplicatesOk,
1428 EncodeCrossCrate::No
1429 ),
1430 rustc_attr!(
1431 TEST, rustc_clean, Normal,
1432 template!(List: &[r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#]),
1433 DuplicatesOk, EncodeCrossCrate::No
1434 ),
1435 rustc_attr!(
1436 TEST, rustc_partition_reused, Normal,
1437 template!(List: &[r#"cfg = "...", module = "...""#]), DuplicatesOk, EncodeCrossCrate::No
1438 ),
1439 rustc_attr!(
1440 TEST, rustc_partition_codegened, Normal,
1441 template!(List: &[r#"cfg = "...", module = "...""#]), DuplicatesOk, EncodeCrossCrate::No
1442 ),
1443 rustc_attr!(
1444 TEST, rustc_expected_cgu_reuse, Normal,
1445 template!(List: &[r#"cfg = "...", module = "...", kind = "...""#]), DuplicatesOk,
1446 EncodeCrossCrate::No
1447 ),
1448 rustc_attr!(
1449 TEST, rustc_symbol_name, Normal, template!(Word),
1450 WarnFollowing, EncodeCrossCrate::No
1451 ),
1452 rustc_attr!(
1453 TEST, rustc_def_path, Normal, template!(Word),
1454 WarnFollowing, EncodeCrossCrate::No
1455 ),
1456 rustc_attr!(
1457 TEST, rustc_mir, Normal, template!(List: &["arg1, arg2, ..."]),
1458 DuplicatesOk, EncodeCrossCrate::Yes
1459 ),
1460 gated!(
1461 custom_mir, Normal, template!(List: &[r#"dialect = "...", phase = "...""#]),
1462 ErrorFollowing, EncodeCrossCrate::No,
1463 "the `#[custom_mir]` attribute is just used for the Rust test suite",
1464 ),
1465 rustc_attr!(
1466 TEST, rustc_dump_item_bounds, Normal, template!(Word),
1467 WarnFollowing, EncodeCrossCrate::No
1468 ),
1469 rustc_attr!(
1470 TEST, rustc_dump_predicates, Normal, template!(Word),
1471 WarnFollowing, EncodeCrossCrate::No
1472 ),
1473 rustc_attr!(
1474 TEST, rustc_dump_def_parents, Normal, template!(Word),
1475 WarnFollowing, EncodeCrossCrate::No
1476 ),
1477 rustc_attr!(
1478 TEST, rustc_object_lifetime_default, Normal, template!(Word),
1479 WarnFollowing, EncodeCrossCrate::No
1480 ),
1481 rustc_attr!(
1482 TEST, rustc_dump_vtable, Normal, template!(Word),
1483 WarnFollowing, EncodeCrossCrate::No
1484 ),
1485 rustc_attr!(
1486 TEST, rustc_dummy, Normal, template!(Word ),
1487 DuplicatesOk, EncodeCrossCrate::No
1488 ),
1489 rustc_attr!(
1490 TEST, pattern_complexity_limit, CrateLevel, template!(NameValueStr: "N"),
1491 ErrorFollowing, EncodeCrossCrate::No,
1492 ),
1493];
1494
1495pub fn is_builtin_attr_name(name: Symbol) -> bool {
1496 BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
1497}
1498
1499pub fn encode_cross_crate(name: Symbol) -> bool {
1502 if let Some(attr) = BUILTIN_ATTRIBUTE_MAP.get(&name) {
1503 attr.encode_cross_crate == EncodeCrossCrate::Yes
1504 } else {
1505 true
1506 }
1507}
1508
1509pub fn is_valid_for_get_attr(name: Symbol) -> bool {
1510 BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| match attr.duplicates {
1511 WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
1512 | FutureWarnPreceding => true,
1513 DuplicatesOk | WarnFollowingWordOnly => false,
1514 })
1515}
1516
1517pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
1518 LazyLock::new(|| {
1519 let mut map = FxHashMap::default();
1520 for attr in BUILTIN_ATTRIBUTES.iter() {
1521 if map.insert(attr.name, attr).is_some() {
1522 panic!("duplicate builtin attribute `{}`", attr.name);
1523 }
1524 }
1525 map
1526 });
1527
1528pub fn is_stable_diagnostic_attribute(sym: Symbol, _features: &Features) -> bool {
1529 match sym {
1530 sym::on_unimplemented | sym::do_not_recommend => true,
1531 _ => false,
1532 }
1533}