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