authorbors <bors@rust-lang.org> 2026-04-14 08:59:40 UTC
committerbors <bors@rust-lang.org> 2026-04-14 08:59:40 UTC
log12f35ad39ed3e39df4d953c46d4f6cc6c82adc96
treea8acc7d526edf073842493756a080e1ec2226bd6
parent7db0ab43a7f248268e6460b96a955e3d420b485d
parenta0f105e63e387e6ce53b792ad7748f5c959e6746

Auto merge of #155209 - JonathanBrouwer:attr_cleanup2, r=jdonszelmann

Post-attribute ports cleanup pt. 1 (again) This is a re-implementation of most (but not all) of https://github.com/rust-lang/rust/pull/154808 The code is the same as in that PR, other than a few changes, I'll leave comments where I changed things. I did re-implement most of the commits rather than cherry-picking, so it's probably good to check the entire diff regardless r? @jdonszelmann

10 files changed, 269 insertions(+), 970 deletions(-)

compiler/rustc_attr_parsing/src/validate_attr.rs+13-18
......@@ -8,8 +8,8 @@ use rustc_ast::tokenstream::DelimSpan;
88use rustc_ast::{
99 self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety,
1010};
11use rustc_errors::{Applicability, FatalError, PResult};
12use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
11use rustc_errors::{Applicability, PResult};
12use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, template};
1313use rustc_hir::AttrPath;
1414use rustc_hir::lints::AttributeLintKind;
1515use rustc_parse::parse_in;
......@@ -30,15 +30,22 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
3030
3131 // Check input tokens for built-in and key-value attributes.
3232 match builtin_attr_info {
33 // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
34 Some(BuiltinAttribute { name, template, .. }) => {
33 Some(BuiltinAttribute { name, .. }) => {
3534 if AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(&name)) {
3635 return;
3736 }
3837 match parse_meta(psess, attr) {
3938 // Don't check safety again, we just did that
4039 Ok(meta) => {
41 check_builtin_meta_item(psess, &meta, attr.style, *name, *template, false)
40 // FIXME The only unparsed builtin attributes that are left are the lint attributes, so we can hardcode the template here
41 let lint_attrs = [sym::forbid, sym::allow, sym::warn, sym::deny, sym::expect];
42 assert!(lint_attrs.contains(name));
43
44 let template = template!(
45 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
46 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
47 );
48 check_builtin_meta_item(psess, &meta, attr.style, *name, template, false)
4249 }
4350 Err(err) => {
4451 err.emit();
......@@ -169,7 +176,7 @@ pub fn check_builtin_meta_item(
169176 }
170177}
171178
172fn emit_malformed_attribute(
179pub fn emit_malformed_attribute(
173180 psess: &ParseSess,
174181 style: ast::AttrStyle,
175182 span: Span,
......@@ -231,15 +238,3 @@ fn emit_malformed_attribute(
231238 err.emit();
232239 }
233240}
234
235pub fn emit_fatal_malformed_builtin_attribute(
236 psess: &ParseSess,
237 attr: &Attribute,
238 name: Symbol,
239) -> ! {
240 let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").template;
241 emit_malformed_attribute(psess, attr.style, attr.span, name, template);
242 // This is fatal, otherwise it will likely cause a cascade of other errors
243 // (and an error here is expected to be very rare).
244 FatalError.raise()
245}
compiler/rustc_expand/src/module.rs+15-2
......@@ -2,12 +2,14 @@ use std::iter::once;
22use std::path::{self, Path, PathBuf};
33
44use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans};
5use rustc_attr_parsing::validate_attr;
5use rustc_attr_parsing::validate_attr::emit_malformed_attribute;
66use rustc_errors::{Diag, ErrorGuaranteed};
7use rustc_feature::template;
78use rustc_parse::lexer::StripTokens;
89use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal};
910use rustc_session::Session;
1011use rustc_session::parse::ParseSess;
12use rustc_span::fatal_error::FatalError;
1113use rustc_span::{Ident, Span, sym};
1214use thin_vec::ThinVec;
1315
......@@ -184,6 +186,7 @@ pub(crate) fn mod_file_path_from_attr(
184186 attrs: &[Attribute],
185187 dir_path: &Path,
186188) -> Option<PathBuf> {
189 // FIXME(154781) use a parsed attribute here
187190 // Extract path string from first `#[path = "path_string"]` attribute.
188191 let first_path = attrs.iter().find(|at| at.has_name(sym::path))?;
189192 let Some(path_sym) = first_path.value_str() else {
......@@ -195,7 +198,17 @@ pub(crate) fn mod_file_path_from_attr(
195198 // Usually bad forms are checked during semantic analysis via
196199 // `TyCtxt::check_mod_attrs`), but by the time that runs the macro
197200 // is expanded, and it doesn't give an error.
198 validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, first_path, sym::path);
201 emit_malformed_attribute(
202 &sess.psess,
203 first_path.style,
204 first_path.span,
205 sym::path,
206 template!(
207 NameValueStr: "file",
208 "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute"
209 ),
210 );
211 FatalError.raise()
199212 };
200213
201214 let path_str = path_sym.as_str();
compiler/rustc_feature/src/builtin_attrs.rs+231-763
......@@ -2,12 +2,9 @@
22
33use std::sync::LazyLock;
44
5use AttributeDuplicates::*;
65use AttributeGate::*;
7use AttributeType::*;
86use rustc_data_structures::fx::FxHashMap;
97use rustc_hir::AttrStyle;
10use rustc_hir::attrs::EncodeCrossCrate;
118use rustc_span::edition::Edition;
129use rustc_span::{Symbol, sym};
1310
......@@ -74,16 +71,6 @@ pub fn find_gated_cfg(pred: impl Fn(Symbol) -> bool) -> Option<&'static GatedCfg
7471// move that documentation into the relevant place in the other docs, and
7572// remove the chapter on the flag.
7673
77#[derive(Copy, Clone, PartialEq, Debug)]
78pub enum AttributeType {
79 /// Normal, builtin attribute that is consumed
80 /// by the compiler before the unused_attribute check
81 Normal,
82
83 /// Builtin attribute that is only allowed at the crate level
84 CrateLevel,
85}
86
8774#[derive(Copy, Clone, PartialEq, Debug)]
8875pub enum AttributeSafety {
8976 /// Normal attribute that does not need `#[unsafe(...)]`
......@@ -182,57 +169,6 @@ impl AttributeTemplate {
182169 }
183170}
184171
185/// How to handle multiple duplicate attributes on the same item.
186#[derive(Clone, Copy, Default)]
187pub enum AttributeDuplicates {
188 /// Duplicates of this attribute are allowed.
189 ///
190 /// This should only be used with attributes where duplicates have semantic
191 /// meaning, or some kind of "additive" behavior. For example, `#[warn(..)]`
192 /// can be specified multiple times, and it combines all the entries. Or use
193 /// this if there is validation done elsewhere.
194 #[default]
195 DuplicatesOk,
196 /// Duplicates after the first attribute will be an unused_attribute warning.
197 ///
198 /// This is usually used for "word" attributes, where they are used as a
199 /// boolean marker, like `#[used]`. It is not necessarily wrong that there
200 /// are duplicates, but the others should probably be removed.
201 WarnFollowing,
202 /// Same as `WarnFollowing`, but only issues warnings for word-style attributes.
203 ///
204 /// This is only for special cases, for example multiple `#[macro_use]` can
205 /// be warned, but multiple `#[macro_use(...)]` should not because the list
206 /// form has different meaning from the word form.
207 WarnFollowingWordOnly,
208 /// Duplicates after the first attribute will be an error.
209 ///
210 /// This should be used where duplicates would be ignored, but carry extra
211 /// meaning that could cause confusion. For example, `#[stable(since="1.0")]
212 /// #[stable(since="2.0")]`, which version should be used for `stable`?
213 ErrorFollowing,
214 /// Duplicates preceding the last instance of the attribute will be an error.
215 ///
216 /// This is the same as `ErrorFollowing`, except the last attribute is the
217 /// one that is "used". This is typically used in cases like codegen
218 /// attributes which usually only honor the last attribute.
219 ErrorPreceding,
220 /// Duplicates after the first attribute will be an unused_attribute warning
221 /// with a note that this will be an error in the future.
222 ///
223 /// This should be used for attributes that should be `ErrorFollowing`, but
224 /// because older versions of rustc silently accepted (and ignored) the
225 /// attributes, this is used to transition.
226 FutureWarnFollowing,
227 /// Duplicates preceding the last instance of the attribute will be a
228 /// warning, with a note that this will be an error in the future.
229 ///
230 /// This is the same as `FutureWarnFollowing`, except the last attribute is
231 /// the one that is "used". Ideally these can eventually migrate to
232 /// `ErrorPreceding`.
233 FutureWarnPreceding,
234}
235
236172/// A convenience macro for constructing attribute templates.
237173/// E.g., `template!(Word, List: "description")` means that the attribute
238174/// supports forms `#[attr]` and `#[attr(description)]`.
......@@ -269,50 +205,30 @@ macro_rules! template {
269205}
270206
271207macro_rules! ungated {
272 (unsafe($edition:ident) $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
208 (unsafe($edition:ident) $attr:ident $(,)?) => {
273209 BuiltinAttribute {
274210 name: sym::$attr,
275 encode_cross_crate: $encode_cross_crate,
276 type_: $typ,
277211 safety: AttributeSafety::Unsafe { unsafe_since: Some(Edition::$edition) },
278 template: $tpl,
279212 gate: Ungated,
280 duplicates: $duplicates,
281213 }
282214 };
283 (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
215 (unsafe $attr:ident $(,)?) => {
284216 BuiltinAttribute {
285217 name: sym::$attr,
286 encode_cross_crate: $encode_cross_crate,
287 type_: $typ,
288218 safety: AttributeSafety::Unsafe { unsafe_since: None },
289 template: $tpl,
290219 gate: Ungated,
291 duplicates: $duplicates,
292220 }
293221 };
294 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
295 BuiltinAttribute {
296 name: sym::$attr,
297 encode_cross_crate: $encode_cross_crate,
298 type_: $typ,
299 safety: AttributeSafety::Normal,
300 template: $tpl,
301 gate: Ungated,
302 duplicates: $duplicates,
303 }
222 ($attr:ident $(,)?) => {
223 BuiltinAttribute { name: sym::$attr, safety: AttributeSafety::Normal, gate: Ungated }
304224 };
305225}
306226
307227macro_rules! gated {
308 (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => {
228 (unsafe $attr:ident, $gate:ident, $message:expr $(,)?) => {
309229 BuiltinAttribute {
310230 name: sym::$attr,
311 encode_cross_crate: $encode_cross_crate,
312 type_: $typ,
313231 safety: AttributeSafety::Unsafe { unsafe_since: None },
314 template: $tpl,
315 duplicates: $duplicates,
316232 gate: Gated {
317233 feature: sym::$gate,
318234 message: $message,
......@@ -321,14 +237,10 @@ macro_rules! gated {
321237 },
322238 }
323239 };
324 (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => {
240 (unsafe $attr:ident, $message:expr $(,)?) => {
325241 BuiltinAttribute {
326242 name: sym::$attr,
327 encode_cross_crate: $encode_cross_crate,
328 type_: $typ,
329243 safety: AttributeSafety::Unsafe { unsafe_since: None },
330 template: $tpl,
331 duplicates: $duplicates,
332244 gate: Gated {
333245 feature: sym::$attr,
334246 message: $message,
......@@ -337,14 +249,10 @@ macro_rules! gated {
337249 },
338250 }
339251 };
340 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $message:expr $(,)?) => {
252 ($attr:ident, $gate:ident, $message:expr $(,)?) => {
341253 BuiltinAttribute {
342254 name: sym::$attr,
343 encode_cross_crate: $encode_cross_crate,
344 type_: $typ,
345255 safety: AttributeSafety::Normal,
346 template: $tpl,
347 duplicates: $duplicates,
348256 gate: Gated {
349257 feature: sym::$gate,
350258 message: $message,
......@@ -353,14 +261,10 @@ macro_rules! gated {
353261 },
354262 }
355263 };
356 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $message:expr $(,)?) => {
264 ($attr:ident, $message:expr $(,)?) => {
357265 BuiltinAttribute {
358266 name: sym::$attr,
359 encode_cross_crate: $encode_cross_crate,
360 type_: $typ,
361267 safety: AttributeSafety::Normal,
362 template: $tpl,
363 duplicates: $duplicates,
364268 gate: Gated {
365269 feature: sym::$attr,
366270 message: $message,
......@@ -372,13 +276,9 @@ macro_rules! gated {
372276}
373277
374278macro_rules! rustc_attr {
375 (TEST, $attr:ident, $typ:expr, $tpl:expr, $duplicate:expr, $encode_cross_crate:expr $(,)?) => {
279 (TEST, $attr:ident $(,)?) => {
376280 rustc_attr!(
377281 $attr,
378 $typ,
379 $tpl,
380 $duplicate,
381 $encode_cross_crate,
382282 concat!(
383283 "the `#[",
384284 stringify!($attr),
......@@ -386,14 +286,10 @@ macro_rules! rustc_attr {
386286 ),
387287 )
388288 };
389 ($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $($notes:expr),* $(,)?) => {
289 ($attr:ident $(, $notes:expr)* $(,)?) => {
390290 BuiltinAttribute {
391291 name: sym::$attr,
392 encode_cross_crate: $encode_cross_crate,
393 type_: $typ,
394292 safety: AttributeSafety::Normal,
395 template: $tpl,
396 duplicates: $duplicates,
397293 gate: Gated {
398294 feature: sym::rustc_attrs,
399295 message: "use of an internal attribute",
......@@ -417,15 +313,7 @@ macro_rules! experimental {
417313
418314pub struct BuiltinAttribute {
419315 pub name: Symbol,
420 /// Whether this attribute is encode cross crate.
421 ///
422 /// If so, it is encoded in the crate metadata.
423 /// Otherwise, it can only be used in the local crate.
424 pub encode_cross_crate: EncodeCrossCrate,
425 pub type_: AttributeType,
426316 pub safety: AttributeSafety,
427 pub template: AttributeTemplate,
428 pub duplicates: AttributeDuplicates,
429317 pub gate: AttributeGate,
430318}
431319
......@@ -437,378 +325,152 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
437325 // ==========================================================================
438326
439327 // Conditional compilation:
440 ungated!(
441 cfg, Normal,
442 template!(
443 List: &["predicate"],
444 "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute"
445 ),
446 DuplicatesOk, EncodeCrossCrate::No
447 ),
448 ungated!(
449 cfg_attr, Normal,
450 template!(
451 List: &["predicate, attr1, attr2, ..."],
452 "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute"
453 ),
454 DuplicatesOk, EncodeCrossCrate::No
455 ),
328 ungated!(cfg),
329 ungated!(cfg_attr),
456330
457331 // Testing:
458 ungated!(
459 ignore, Normal,
460 template!(
461 Word,
462 NameValueStr: "reason",
463 "https://doc.rust-lang.org/reference/attributes/testing.html#the-ignore-attribute"
464 ),
465 WarnFollowing, EncodeCrossCrate::No,
466 ),
467 ungated!(
468 should_panic, Normal,
469 template!(
470 Word,
471 List: &[r#"expected = "reason""#],
472 NameValueStr: "reason",
473 "https://doc.rust-lang.org/reference/attributes/testing.html#the-should_panic-attribute"
474 ),
475 FutureWarnFollowing, EncodeCrossCrate::No,
476 ),
332 ungated!(ignore),
333 ungated!(should_panic),
477334
478335 // Macros:
479 ungated!(
480 automatically_derived, Normal,
481 template!(
482 Word,
483 "https://doc.rust-lang.org/reference/attributes/derive.html#the-automatically_derived-attribute"
484 ),
485 WarnFollowing, EncodeCrossCrate::Yes
486 ),
487 ungated!(
488 macro_use, Normal,
489 template!(
490 Word,
491 List: &["name1, name2, ..."],
492 "https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute"
493 ),
494 WarnFollowingWordOnly, EncodeCrossCrate::No,
495 ),
496 ungated!(macro_escape, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No), // Deprecated synonym for `macro_use`.
497 ungated!(
498 macro_export, Normal,
499 template!(
500 Word,
501 List: &["local_inner_macros"],
502 "https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope"
503 ),
504 WarnFollowing, EncodeCrossCrate::Yes
505 ),
506 ungated!(
507 proc_macro, Normal,
508 template!(
509 Word,
510 "https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros"),
511 ErrorFollowing, EncodeCrossCrate::No
512 ),
513 ungated!(
514 proc_macro_derive, Normal,
515 template!(
516 List: &["TraitName", "TraitName, attributes(name1, name2, ...)"],
517 "https://doc.rust-lang.org/reference/procedural-macros.html#derive-macros"
518 ),
519 ErrorFollowing, EncodeCrossCrate::No,
520 ),
521 ungated!(
522 proc_macro_attribute, Normal,
523 template!(Word, "https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros"),
524 ErrorFollowing, EncodeCrossCrate::No
525 ),
336 ungated!(automatically_derived),
337 ungated!(macro_use),
338 ungated!(macro_escape), // Deprecated synonym for `macro_use`.
339 ungated!(macro_export),
340 ungated!(proc_macro),
341 ungated!(proc_macro_derive),
342 ungated!(proc_macro_attribute),
526343
527344 // Lints:
528 ungated!(
529 warn, Normal,
530 template!(
531 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
532 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
533 ),
534 DuplicatesOk, EncodeCrossCrate::No,
535 ),
536 ungated!(
537 allow, Normal,
538 template!(
539 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
540 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
541 ),
542 DuplicatesOk, EncodeCrossCrate::No,
543 ),
544 ungated!(
545 expect, Normal,
546 template!(
547 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
548 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
549 ),
550 DuplicatesOk, EncodeCrossCrate::No,
551 ),
552 ungated!(
553 forbid, Normal,
554 template!(
555 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
556 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
557 ),
558 DuplicatesOk, EncodeCrossCrate::No
559 ),
560 ungated!(
561 deny, Normal,
562 template!(
563 List: &["lint1", "lint1, lint2, ...", r#"lint1, lint2, lint3, reason = "...""#],
564 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#lint-check-attributes"
565 ),
566 DuplicatesOk, EncodeCrossCrate::No
567 ),
568 ungated!(
569 must_use, Normal,
570 template!(
571 Word,
572 NameValueStr: "reason",
573 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"
574 ),
575 FutureWarnFollowing, EncodeCrossCrate::Yes
576 ),
345 ungated!(warn),
346 ungated!(allow),
347 ungated!(expect),
348 ungated!(forbid),
349 ungated!(deny),
350 ungated!(must_use),
577351 gated!(
578 must_not_suspend, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
579 EncodeCrossCrate::Yes, experimental!(must_not_suspend)
580 ),
581 ungated!(
582 deprecated, Normal,
583 template!(
584 Word,
585 List: &[r#"/*opt*/ since = "version", /*opt*/ note = "reason""#],
586 NameValueStr: "reason",
587 "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute"
588 ),
589 ErrorFollowing, EncodeCrossCrate::Yes
352 must_not_suspend,
353 experimental!(must_not_suspend)
590354 ),
355 ungated!(deprecated),
591356
592357 // Crate properties:
593 ungated!(
594 crate_name, CrateLevel,
595 template!(
596 NameValueStr: "name",
597 "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-crate_name-attribute"
598 ),
599 FutureWarnFollowing, EncodeCrossCrate::No,
600 ),
601 ungated!(
602 crate_type, CrateLevel,
603 template!(
604 NameValueStr: ["bin", "lib", "dylib", "cdylib", "rlib", "staticlib", "sdylib", "proc-macro"],
605 "https://doc.rust-lang.org/reference/linkage.html"
606 ),
607 DuplicatesOk, EncodeCrossCrate::No,
608 ),
358 ungated!(crate_name),
359 ungated!(crate_type),
609360
610361 // ABI, linking, symbols, and FFI
611 ungated!(
612 link, Normal,
613 template!(List: &[
614 r#"name = "...""#,
615 r#"name = "...", kind = "dylib|static|...""#,
616 r#"name = "...", wasm_import_module = "...""#,
617 r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#,
618 r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#,
619 ], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute"),
620 DuplicatesOk, EncodeCrossCrate::No,
621 ),
622 ungated!(
623 link_name, Normal,
624 template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_name-attribute"),
625 FutureWarnPreceding, EncodeCrossCrate::Yes
626 ),
627 ungated!(
628 no_link, Normal,
629 template!(Word, "https://doc.rust-lang.org/reference/items/extern-crates.html#the-no_link-attribute"),
630 WarnFollowing, EncodeCrossCrate::No
631 ),
632 ungated!(
633 repr, Normal,
634 template!(
635 List: &["C", "Rust", "transparent", "align(...)", "packed(...)", "<integer type>"],
636 "https://doc.rust-lang.org/reference/type-layout.html#representations"
637 ),
638 DuplicatesOk, EncodeCrossCrate::No
639 ),
362 ungated!(link),
363 ungated!(link_name),
364 ungated!(no_link),
365 ungated!(repr),
640366 // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
641 gated!(rustc_align, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
642 gated!(rustc_align_static, Normal, template!(List: &["alignment"]), DuplicatesOk, EncodeCrossCrate::No, static_align, experimental!(rustc_align_static)),
367 gated!(rustc_align, fn_align, experimental!(rustc_align)),
368 gated!(rustc_align_static, static_align, experimental!(rustc_align_static)),
643369 ungated!(
644 unsafe(Edition2024) export_name, Normal,
645 template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute"),
646 FutureWarnPreceding, EncodeCrossCrate::No
370 unsafe(Edition2024) export_name,
647371 ),
648372 ungated!(
649 unsafe(Edition2024) link_section, Normal,
650 template!(NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute"),
651 FutureWarnPreceding, EncodeCrossCrate::No
373 unsafe(Edition2024) link_section,
652374 ),
653375 ungated!(
654 unsafe(Edition2024) no_mangle, Normal,
655 template!(Word, "https://doc.rust-lang.org/reference/abi.html#the-no_mangle-attribute"),
656 WarnFollowing, EncodeCrossCrate::No
376 unsafe(Edition2024) no_mangle,
657377 ),
658378 ungated!(
659 used, Normal,
660 template!(Word, List: &["compiler", "linker"], "https://doc.rust-lang.org/reference/abi.html#the-used-attribute"),
661 WarnFollowing, EncodeCrossCrate::No
379 used,
662380 ),
663381 ungated!(
664 link_ordinal, Normal,
665 template!(List: &["ordinal"], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link_ordinal-attribute"),
666 ErrorPreceding, EncodeCrossCrate::Yes
382 link_ordinal,
667383 ),
668384 ungated!(
669 unsafe naked, Normal,
670 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-naked-attribute"),
671 WarnFollowing, EncodeCrossCrate::No
385 unsafe naked,
672386 ),
673387 // See `TyAndLayout::pass_indirectly_in_non_rustic_abis` for details.
674388 rustc_attr!(
675 rustc_pass_indirectly_in_non_rustic_abis, Normal, template!(Word), ErrorFollowing,
676 EncodeCrossCrate::No,
389 rustc_pass_indirectly_in_non_rustic_abis,
677390 "types marked with `#[rustc_pass_indirectly_in_non_rustic_abis]` are always passed indirectly by non-Rustic ABIs"
678391 ),
679392
680393 // Limits:
681394 ungated!(
682 recursion_limit, CrateLevel,
683 template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"),
684 FutureWarnFollowing, EncodeCrossCrate::No
395 recursion_limit,
685396 ),
686397 ungated!(
687 type_length_limit, CrateLevel,
688 template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-type_length_limit-attribute"),
689 FutureWarnFollowing, EncodeCrossCrate::No
398 type_length_limit,
690399 ),
691400 gated!(
692 move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
693 EncodeCrossCrate::No, large_assignments, experimental!(move_size_limit)
401 move_size_limit,
402 large_assignments, experimental!(move_size_limit)
694403 ),
695404
696405 // Entry point:
697406 ungated!(
698 no_main, CrateLevel,
699 template!(Word, "https://doc.rust-lang.org/reference/crates-and-source-files.html#the-no_main-attribute"),
700 WarnFollowing, EncodeCrossCrate::No
407 no_main,
701408 ),
702409
703410 // Modules, prelude, and resolution:
704411 ungated!(
705 path, Normal,
706 template!(NameValueStr: "file", "https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute"),
707 FutureWarnFollowing, EncodeCrossCrate::No
412 path,
708413 ),
709414 ungated!(
710 no_std, CrateLevel,
711 template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute"),
712 WarnFollowing, EncodeCrossCrate::No
415 no_std,
713416 ),
714417 ungated!(
715 no_implicit_prelude, Normal,
716 template!(Word, "https://doc.rust-lang.org/reference/names/preludes.html#the-no_implicit_prelude-attribute"),
717 WarnFollowing, EncodeCrossCrate::No
418 no_implicit_prelude,
718419 ),
719420 ungated!(
720 non_exhaustive, Normal,
721 template!(Word, "https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute"),
722 WarnFollowing, EncodeCrossCrate::Yes
421 non_exhaustive,
723422 ),
724423
725424 // Runtime
726425 ungated!(
727 windows_subsystem, CrateLevel,
728 template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute"),
729 FutureWarnFollowing, EncodeCrossCrate::No
426 windows_subsystem,
730427 ),
731428 ungated!( // RFC 2070
732 panic_handler, Normal,
733 template!(Word, "https://doc.rust-lang.org/reference/panic.html#the-panic_handler-attribute"),
734 WarnFollowing, EncodeCrossCrate::Yes
429 panic_handler,
735430 ),
736431
737432 // Code generation:
738433 ungated!(
739 inline, Normal,
740 template!(
741 Word,
742 List: &["always", "never"],
743 "https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute"
744 ),
745 FutureWarnFollowing, EncodeCrossCrate::No
434 inline,
746435 ),
747436 ungated!(
748 cold, Normal,
749 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-cold-attribute"),
750 WarnFollowing, EncodeCrossCrate::No
437 cold,
751438 ),
752439 ungated!(
753 no_builtins, CrateLevel,
754 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-no_builtins-attribute"),
755 WarnFollowing, EncodeCrossCrate::Yes
440 no_builtins,
756441 ),
757442 ungated!(
758 target_feature, Normal,
759 template!(List: &[r#"enable = "name""#], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-target_feature-attribute"),
760 DuplicatesOk, EncodeCrossCrate::No,
443 target_feature,
761444 ),
762445 ungated!(
763 track_caller, Normal,
764 template!(Word, "https://doc.rust-lang.org/reference/attributes/codegen.html#the-track_caller-attribute"),
765 WarnFollowing, EncodeCrossCrate::Yes
446 track_caller,
766447 ),
767448 ungated!(
768 instruction_set, Normal,
769 template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"),
770 ErrorPreceding, EncodeCrossCrate::No
449 instruction_set,
771450 ),
772451 gated!(
773 unsafe force_target_feature, Normal, template!(List: &[r#"enable = "name""#]),
774 DuplicatesOk, EncodeCrossCrate::No, effective_target_features, experimental!(force_target_feature)
452 unsafe force_target_feature,
453 effective_target_features, experimental!(force_target_feature)
775454 ),
776455 gated!(
777 sanitize, Normal, template!(List: &[r#"address = "on|off""#, r#"kernel_address = "on|off""#, r#"cfi = "on|off""#, r#"hwaddress = "on|off""#, r#"kernel_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,
778 EncodeCrossCrate::No, sanitize, experimental!(sanitize),
456 sanitize,
457 sanitize, experimental!(sanitize),
779458 ),
780459 gated!(
781 coverage, Normal, template!(OneOf: &[sym::off, sym::on]),
782 ErrorPreceding, EncodeCrossCrate::No,
460 coverage,
783461 coverage_attribute, experimental!(coverage)
784462 ),
785463
786464 ungated!(
787 doc, Normal,
788 template!(
789 List: &["hidden", "inline"],
790 NameValueStr: "string",
791 "https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html"
792 ),
793 DuplicatesOk, EncodeCrossCrate::Yes
465 doc,
794466 ),
795467
796468 // Debugging
797469 ungated!(
798 debugger_visualizer, Normal,
799 template!(
800 List: &[r#"natvis_file = "...", gdb_script_file = "...""#],
801 "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute"
802 ),
803 DuplicatesOk, EncodeCrossCrate::No
470 debugger_visualizer,
804471 ),
805472 ungated!(
806 collapse_debuginfo, Normal,
807 template!(
808 List: &["no", "external", "yes"],
809 "https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
810 ),
811 ErrorFollowing, EncodeCrossCrate::Yes
473 collapse_debuginfo,
812474 ),
813475
814476 // ==========================================================================
......@@ -817,71 +479,71 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
817479
818480 // Linking:
819481 gated!(
820 export_stable, Normal, template!(Word), WarnFollowing,
821 EncodeCrossCrate::No, experimental!(export_stable)
482 export_stable,
483 experimental!(export_stable)
822484 ),
823485
824486 // Testing:
825487 gated!(
826 test_runner, CrateLevel, template!(List: &["path"]), ErrorFollowing,
827 EncodeCrossCrate::Yes, custom_test_frameworks,
488 test_runner,
489 custom_test_frameworks,
828490 "custom test frameworks are an unstable feature",
829491 ),
830492
831493 gated!(
832 reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing,
833 EncodeCrossCrate::No, custom_test_frameworks,
494 reexport_test_harness_main,
495 custom_test_frameworks,
834496 "custom test frameworks are an unstable feature",
835497 ),
836498
837499 // RFC #1268
838500 gated!(
839 marker, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
501 marker,
840502 marker_trait_attr, experimental!(marker)
841503 ),
842504 gated!(
843 thread_local, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
505 thread_local,
844506 "`#[thread_local]` is an experimental feature, and does not currently handle destructors",
845507 ),
846508 gated!(
847 no_core, CrateLevel, template!(Word), WarnFollowing,
848 EncodeCrossCrate::No, experimental!(no_core)
509 no_core,
510 experimental!(no_core)
849511 ),
850512 // RFC 2412
851513 gated!(
852 optimize, Normal, template!(List: &["none", "size", "speed"]), ErrorPreceding,
853 EncodeCrossCrate::No, optimize_attribute, experimental!(optimize)
514 optimize,
515 optimize_attribute, experimental!(optimize)
854516 ),
855517
856518 gated!(
857 unsafe ffi_pure, Normal, template!(Word), WarnFollowing,
858 EncodeCrossCrate::No, experimental!(ffi_pure)
519 unsafe ffi_pure,
520 experimental!(ffi_pure)
859521 ),
860522 gated!(
861 unsafe ffi_const, Normal, template!(Word), WarnFollowing,
862 EncodeCrossCrate::No, experimental!(ffi_const)
523 unsafe ffi_const,
524 experimental!(ffi_const)
863525 ),
864526 gated!(
865 register_tool, CrateLevel, template!(List: &["tool1, tool2, ..."]), DuplicatesOk,
866 EncodeCrossCrate::No, experimental!(register_tool),
527 register_tool,
528 experimental!(register_tool),
867529 ),
868530 // `#[cfi_encoding = ""]`
869531 gated!(
870 cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding,
871 EncodeCrossCrate::Yes, experimental!(cfi_encoding)
532 cfi_encoding,
533 experimental!(cfi_encoding)
872534 ),
873535
874536 // `#[coroutine]` attribute to be applied to closures to make them coroutines instead
875537 gated!(
876 coroutine, Normal, template!(Word), ErrorFollowing,
877 EncodeCrossCrate::No, coroutines, experimental!(coroutine)
538 coroutine,
539 coroutines, experimental!(coroutine)
878540 ),
879541
880542 // RFC 3543
881543 // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
882544 gated!(
883 patchable_function_entry, Normal, template!(List: &["prefix_nops = m, entry_nops = n"]), ErrorPreceding,
884 EncodeCrossCrate::Yes, experimental!(patchable_function_entry)
545 patchable_function_entry,
546 experimental!(patchable_function_entry)
885547 ),
886548
887549 // The `#[loop_match]` and `#[const_continue]` attributes are part of the
......@@ -889,12 +551,12 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
889551 //
890552 // - https://github.com/rust-lang/rust/issues/132306
891553 gated!(
892 const_continue, Normal, template!(Word), ErrorFollowing,
893 EncodeCrossCrate::No, loop_match, experimental!(const_continue)
554 const_continue,
555 loop_match, experimental!(const_continue)
894556 ),
895557 gated!(
896 loop_match, Normal, template!(Word), ErrorFollowing,
897 EncodeCrossCrate::No, loop_match, experimental!(loop_match)
558 loop_match,
559 loop_match, experimental!(loop_match)
898560 ),
899561
900562 // The `#[pin_v2]` attribute is part of the `pin_ergonomics` experiment
......@@ -902,8 +564,8 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
902564 //
903565 // - https://github.com/rust-lang/rust/issues/130494
904566 gated!(
905 pin_v2, Normal, template!(Word), ErrorFollowing,
906 EncodeCrossCrate::Yes, pin_ergonomics, experimental!(pin_v2),
567 pin_v2,
568 pin_ergonomics, experimental!(pin_v2),
907569 ),
908570
909571 // ==========================================================================
......@@ -911,69 +573,44 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
911573 // ==========================================================================
912574
913575 ungated!(
914 feature, CrateLevel,
915 template!(List: &["name1, name2, ..."]), DuplicatesOk, EncodeCrossCrate::No,
576 feature,
916577 ),
917578 // DuplicatesOk since it has its own validation
918579 ungated!(
919 stable, Normal,
920 template!(List: &[r#"feature = "name", since = "version""#]), DuplicatesOk, EncodeCrossCrate::No,
921 ),
922 ungated!(
923 unstable, Normal,
924 template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]), DuplicatesOk,
925 EncodeCrossCrate::Yes
926 ),
927 ungated!(
928 unstable_feature_bound, Normal, template!(Word, List: &["feat1, feat2, ..."]),
929 DuplicatesOk, EncodeCrossCrate::No,
930 ),
931 ungated!(
932 unstable_removed, CrateLevel,
933 template!(List: &[r#"feature = "name", reason = "...", link = "...", since = "version""#]),
934 DuplicatesOk, EncodeCrossCrate::Yes
580 stable,
935581 ),
936582 ungated!(
937 rustc_const_unstable, Normal, template!(List: &[r#"feature = "name""#]),
938 DuplicatesOk, EncodeCrossCrate::Yes
939 ),
940 ungated!(
941 rustc_const_stable, Normal,
942 template!(List: &[r#"feature = "name""#]), DuplicatesOk, EncodeCrossCrate::No,
943 ),
944 ungated!(
945 rustc_default_body_unstable, Normal,
946 template!(List: &[r#"feature = "name", reason = "...", issue = "N""#]),
947 DuplicatesOk, EncodeCrossCrate::No
583 unstable,
948584 ),
585 ungated!(unstable_feature_bound),
586 ungated!(unstable_removed),
587 ungated!(rustc_const_unstable),
588 ungated!(rustc_const_stable),
589 ungated!(rustc_default_body_unstable),
949590 gated!(
950 allow_internal_unstable, Normal, template!(Word, List: &["feat1, feat2, ..."]),
951 DuplicatesOk, EncodeCrossCrate::Yes,
591 allow_internal_unstable,
952592 "allow_internal_unstable side-steps feature gating and stability checks",
953593 ),
954594 gated!(
955 allow_internal_unsafe, Normal, template!(Word), WarnFollowing,
956 EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
595 allow_internal_unsafe,
596 "allow_internal_unsafe side-steps the unsafe_code lint",
957597 ),
958598 gated!(
959 rustc_eii_foreign_item, Normal, template!(Word),
960 ErrorFollowing, EncodeCrossCrate::Yes, eii_internals,
599 rustc_eii_foreign_item,
600 eii_internals,
961601 "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
962602 ),
963603 rustc_attr!(
964 rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"),
965 WarnFollowing, EncodeCrossCrate::No,
604 rustc_allowed_through_unstable_modules,
966605 "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
967606 through unstable paths"
968607 ),
969608 rustc_attr!(
970 rustc_deprecated_safe_2024, Normal, template!(List: &[r#"audit_that = "...""#]),
971 ErrorFollowing, EncodeCrossCrate::Yes,
609 rustc_deprecated_safe_2024,
972610 "`#[rustc_deprecated_safe_2024]` is used to declare functions unsafe across the edition 2024 boundary",
973611 ),
974612 rustc_attr!(
975 rustc_pub_transparent, Normal, template!(Word),
976 ErrorFollowing, EncodeCrossCrate::Yes,
613 rustc_pub_transparent,
977614 "used internally to mark types with a `transparent` representation when it is guaranteed by the documentation",
978615 ),
979616
......@@ -982,25 +619,15 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
982619 // Internal attributes: Type system related:
983620 // ==========================================================================
984621
985 gated!(fundamental, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes, experimental!(fundamental)),
622 gated!(fundamental, experimental!(fundamental)),
986623 gated!(
987 may_dangle, Normal, template!(Word), WarnFollowing,
988 EncodeCrossCrate::No, dropck_eyepatch,
624 may_dangle,
625 dropck_eyepatch,
989626 "`may_dangle` has unstable semantics and may be removed in the future",
990627 ),
991628
992629 rustc_attr!(
993630 rustc_never_type_options,
994 Normal,
995 template!(List: &[
996 "",
997 r#"fallback = "unit""#,
998 r#"fallback = "niko""#,
999 r#"fallback = "never""#,
1000 r#"fallback = "no""#,
1001 ]),
1002 ErrorFollowing,
1003 EncodeCrossCrate::No,
1004631 "`rustc_never_type_options` is used to experiment with never type fallback and work on \
1005632 never type stabilization"
1006633 ),
......@@ -1010,54 +637,46 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
1010637 // ==========================================================================
1011638
1012639 rustc_attr!(
1013 rustc_allocator, Normal, template!(Word), WarnFollowing,
1014 EncodeCrossCrate::No,
640 rustc_allocator,
1015641 ),
1016642 rustc_attr!(
1017 rustc_nounwind, Normal, template!(Word), WarnFollowing,
1018 EncodeCrossCrate::No,
643 rustc_nounwind,
1019644 ),
1020645 rustc_attr!(
1021 rustc_reallocator, Normal, template!(Word), WarnFollowing,
1022 EncodeCrossCrate::No,
646 rustc_reallocator,
1023647 ),
1024648 rustc_attr!(
1025 rustc_deallocator, Normal, template!(Word), WarnFollowing,
1026 EncodeCrossCrate::No,
649 rustc_deallocator,
1027650 ),
1028651 rustc_attr!(
1029 rustc_allocator_zeroed, Normal, template!(Word), WarnFollowing,
1030 EncodeCrossCrate::No,
652 rustc_allocator_zeroed,
1031653 ),
1032654 rustc_attr!(
1033 rustc_allocator_zeroed_variant, Normal, template!(NameValueStr: "function"), ErrorPreceding,
1034 EncodeCrossCrate::Yes,
655 rustc_allocator_zeroed_variant,
1035656 ),
1036657 gated!(
1037 default_lib_allocator, Normal, template!(Word), WarnFollowing,
1038 EncodeCrossCrate::No, allocator_internals, experimental!(default_lib_allocator),
658 default_lib_allocator,
659 allocator_internals, experimental!(default_lib_allocator),
1039660 ),
1040661 gated!(
1041 needs_allocator, Normal, template!(Word), WarnFollowing,
1042 EncodeCrossCrate::No, allocator_internals, experimental!(needs_allocator),
662 needs_allocator,
663 allocator_internals, experimental!(needs_allocator),
1043664 ),
1044665 gated!(
1045 panic_runtime, CrateLevel, template!(Word), WarnFollowing,
1046 EncodeCrossCrate::No, experimental!(panic_runtime)
666 panic_runtime,
667 experimental!(panic_runtime)
1047668 ),
1048669 gated!(
1049 needs_panic_runtime, CrateLevel, template!(Word), WarnFollowing,
1050 EncodeCrossCrate::No, experimental!(needs_panic_runtime)
670 needs_panic_runtime,
671 experimental!(needs_panic_runtime)
1051672 ),
1052673 gated!(
1053 compiler_builtins, CrateLevel, template!(Word), WarnFollowing,
1054 EncodeCrossCrate::No,
674 compiler_builtins,
1055675 "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
1056676 which contains compiler-rt intrinsics and will never be stable",
1057677 ),
1058678 gated!(
1059 profiler_runtime, CrateLevel, template!(Word), WarnFollowing,
1060 EncodeCrossCrate::No,
679 profiler_runtime,
1061680 "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
1062681 which contains the profiler runtime and will never be stable",
1063682 ),
......@@ -1067,126 +686,71 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
1067686 // ==========================================================================
1068687
1069688 gated!(
1070 linkage, Normal, template!(NameValueStr: [
1071 "available_externally",
1072 "common",
1073 "extern_weak",
1074 "external",
1075 "internal",
1076 "linkonce",
1077 "linkonce_odr",
1078 "weak",
1079 "weak_odr",
1080 ], "https://doc.rust-lang.org/reference/linkage.html"),
1081 ErrorPreceding, EncodeCrossCrate::No,
689 linkage,
1082690 "the `linkage` attribute is experimental and not portable across platforms",
1083691 ),
1084 rustc_attr!(
1085 rustc_std_internal_symbol, Normal, template!(Word), WarnFollowing,
1086 EncodeCrossCrate::No,
1087 ),
1088 rustc_attr!(
1089 rustc_objc_class, Normal, template!(NameValueStr: "ClassName"), ErrorPreceding,
1090 EncodeCrossCrate::No,
1091 ),
1092 rustc_attr!(
1093 rustc_objc_selector, Normal, template!(NameValueStr: "methodName"), ErrorPreceding,
1094 EncodeCrossCrate::No,
1095 ),
692 rustc_attr!(rustc_std_internal_symbol),
693 rustc_attr!(rustc_objc_class),
694 rustc_attr!(rustc_objc_selector),
1096695
1097696 // ==========================================================================
1098697 // Internal attributes, Macro related:
1099698 // ==========================================================================
1100699
700 rustc_attr!(rustc_builtin_macro),
701 rustc_attr!(rustc_proc_macro_decls),
1101702 rustc_attr!(
1102 rustc_builtin_macro, Normal,
1103 template!(Word, List: &["name", "name, /*opt*/ attributes(name1, name2, ...)"]), ErrorFollowing,
1104 EncodeCrossCrate::Yes,
1105 ),
1106 rustc_attr!(
1107 rustc_proc_macro_decls, Normal, template!(Word), WarnFollowing,
1108 EncodeCrossCrate::No,
1109 ),
1110 rustc_attr!(
1111 rustc_macro_transparency, Normal,
1112 template!(NameValueStr: ["transparent", "semiopaque", "opaque"]), ErrorFollowing,
1113 EncodeCrossCrate::Yes, "used internally for testing macro hygiene",
1114 ),
1115 rustc_attr!(
1116 rustc_autodiff, Normal,
1117 template!(Word, List: &[r#""...""#]), DuplicatesOk,
1118 EncodeCrossCrate::Yes,
1119 ),
1120 rustc_attr!(
1121 rustc_offload_kernel, Normal,
1122 template!(Word), DuplicatesOk,
1123 EncodeCrossCrate::Yes,
703 rustc_macro_transparency,
704 "used internally for testing macro hygiene",
1124705 ),
706 rustc_attr!(rustc_autodiff),
707 rustc_attr!(rustc_offload_kernel),
1125708 // Traces that are left when `cfg` and `cfg_attr` attributes are expanded.
1126709 // The attributes are not gated, to avoid stability errors, but they cannot be used in stable
1127710 // or unstable code directly because `sym::cfg_(attr_)trace` are not valid identifiers, they
1128711 // can only be generated by the compiler.
1129 ungated!(
1130 cfg_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk,
1131 EncodeCrossCrate::Yes
1132 ),
1133 ungated!(
1134 cfg_attr_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk,
1135 EncodeCrossCrate::No
1136 ),
712 ungated!(cfg_trace),
713 ungated!(cfg_attr_trace),
1137714
1138715 // ==========================================================================
1139716 // Internal attributes, Diagnostics related:
1140717 // ==========================================================================
1141718
1142719 rustc_attr!(
1143 rustc_on_unimplemented, Normal,
1144 template!(
1145 List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#],
1146 NameValueStr: "message"
1147 ),
1148 ErrorFollowing, EncodeCrossCrate::Yes,
720 rustc_on_unimplemented,
1149721 "see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute"
1150722 ),
1151723 rustc_attr!(
1152 rustc_confusables, Normal,
1153 template!(List: &[r#""name1", "name2", ..."#]),
1154 ErrorFollowing, EncodeCrossCrate::Yes,
724 rustc_confusables,
1155725 ),
1156726 // Enumerates "identity-like" conversion methods to suggest on type mismatch.
1157727 rustc_attr!(
1158 rustc_conversion_suggestion, Normal, template!(Word),
1159 WarnFollowing, EncodeCrossCrate::Yes,
728 rustc_conversion_suggestion,
1160729 ),
1161730 // Prevents field reads in the marked trait or method to be considered
1162731 // during dead code analysis.
1163732 rustc_attr!(
1164 rustc_trivial_field_reads, Normal, template!(Word),
1165 WarnFollowing, EncodeCrossCrate::Yes,
733 rustc_trivial_field_reads,
1166734 ),
1167735 // Used by the `rustc::potential_query_instability` lint to warn methods which
1168736 // might not be stable during incremental compilation.
1169737 rustc_attr!(
1170 rustc_lint_query_instability, Normal, template!(Word),
1171 WarnFollowing, EncodeCrossCrate::Yes,
738 rustc_lint_query_instability,
1172739 ),
1173740 // Used by the `rustc::untracked_query_information` lint to warn methods which
1174741 // might not be stable during incremental compilation.
1175742 rustc_attr!(
1176 rustc_lint_untracked_query_information, Normal, template!(Word),
1177 WarnFollowing, EncodeCrossCrate::Yes,
743 rustc_lint_untracked_query_information,
1178744 ),
1179745 // Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions`
1180746 // types (as well as any others in future).
1181747 rustc_attr!(
1182 rustc_lint_opt_ty, Normal, template!(Word),
1183 WarnFollowing, EncodeCrossCrate::Yes,
748 rustc_lint_opt_ty,
1184749 ),
1185750 // Used by the `rustc::bad_opt_access` lint on fields
1186751 // types (as well as any others in future).
1187752 rustc_attr!(
1188 rustc_lint_opt_deny_field_access, Normal, template!(List: &["message"]),
1189 WarnFollowing, EncodeCrossCrate::Yes,
753 rustc_lint_opt_deny_field_access,
1190754 ),
1191755
1192756 // ==========================================================================
......@@ -1194,31 +758,26 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
1194758 // ==========================================================================
1195759
1196760 rustc_attr!(
1197 rustc_promotable, Normal, template!(Word), WarnFollowing,
1198 EncodeCrossCrate::No, ),
761 rustc_promotable,
762 ),
1199763 rustc_attr!(
1200 rustc_legacy_const_generics, Normal, template!(List: &["N"]), ErrorFollowing,
1201 EncodeCrossCrate::Yes,
764 rustc_legacy_const_generics,
1202765 ),
1203766 // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`.
1204767 rustc_attr!(
1205 rustc_do_not_const_check, Normal, template!(Word), WarnFollowing,
1206 EncodeCrossCrate::Yes, "`#[rustc_do_not_const_check]` skips const-check for this function's body",
768 rustc_do_not_const_check,
769 "`#[rustc_do_not_const_check]` skips const-check for this function's body",
1207770 ),
1208771 rustc_attr!(
1209 rustc_const_stable_indirect, Normal,
1210 template!(Word),
1211 WarnFollowing,
1212 EncodeCrossCrate::No,
772 rustc_const_stable_indirect,
1213773 "this is an internal implementation detail",
1214774 ),
1215775 rustc_attr!(
1216 rustc_intrinsic_const_stable_indirect, Normal,
1217 template!(Word), WarnFollowing, EncodeCrossCrate::No, "this is an internal implementation detail",
776 rustc_intrinsic_const_stable_indirect,
777 "this is an internal implementation detail",
1218778 ),
1219779 rustc_attr!(
1220 rustc_allow_const_fn_unstable, Normal,
1221 template!(Word, List: &["feat1, feat2, ..."]), DuplicatesOk, EncodeCrossCrate::No,
780 rustc_allow_const_fn_unstable,
1222781 "rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
1223782 ),
1224783
......@@ -1227,26 +786,22 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
1227786 // ==========================================================================
1228787
1229788 rustc_attr!(
1230 rustc_layout_scalar_valid_range_start, Normal, template!(List: &["value"]), ErrorFollowing,
1231 EncodeCrossCrate::Yes,
789 rustc_layout_scalar_valid_range_start,
1232790 "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
1233791 niche optimizations in the standard library",
1234792 ),
1235793 rustc_attr!(
1236 rustc_layout_scalar_valid_range_end, Normal, template!(List: &["value"]), ErrorFollowing,
1237 EncodeCrossCrate::Yes,
794 rustc_layout_scalar_valid_range_end,
1238795 "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
1239796 niche optimizations in the standard library",
1240797 ),
1241798 rustc_attr!(
1242 rustc_simd_monomorphize_lane_limit, Normal, template!(NameValueStr: "N"), ErrorFollowing,
1243 EncodeCrossCrate::Yes,
799 rustc_simd_monomorphize_lane_limit,
1244800 "the `#[rustc_simd_monomorphize_lane_limit]` attribute is just used by std::simd \
1245801 for better error messages",
1246802 ),
1247803 rustc_attr!(
1248 rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
1249 EncodeCrossCrate::Yes,
804 rustc_nonnull_optimization_guaranteed,
1250805 "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document \
1251806 guaranteed niche optimizations in the standard library",
1252807 "the compiler does not even check whether the type indeed is being non-null-optimized; \
......@@ -1257,87 +812,68 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
1257812 // Internal attributes, Misc:
1258813 // ==========================================================================
1259814 gated!(
1260 lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, EncodeCrossCrate::No, lang_items,
815 lang, lang_items,
1261816 "lang items are subject to change",
1262817 ),
1263818 rustc_attr!(
1264 rustc_as_ptr, Normal, template!(Word), ErrorFollowing,
1265 EncodeCrossCrate::Yes,
819 rustc_as_ptr,
1266820 "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations"
1267821 ),
1268822 rustc_attr!(
1269 rustc_should_not_be_called_on_const_items, Normal, template!(Word), ErrorFollowing,
1270 EncodeCrossCrate::Yes,
823 rustc_should_not_be_called_on_const_items,
1271824 "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts"
1272825 ),
1273826 rustc_attr!(
1274 rustc_pass_by_value, Normal, template!(Word), ErrorFollowing,
1275 EncodeCrossCrate::Yes,
827 rustc_pass_by_value,
1276828 "`#[rustc_pass_by_value]` is used to mark types that must be passed by value instead of reference"
1277829 ),
1278830 rustc_attr!(
1279 rustc_never_returns_null_ptr, Normal, template!(Word), ErrorFollowing,
1280 EncodeCrossCrate::Yes,
831 rustc_never_returns_null_ptr,
1281832 "`#[rustc_never_returns_null_ptr]` is used to mark functions returning non-null pointers"
1282833 ),
1283834 rustc_attr!(
1284 rustc_no_implicit_autorefs, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
835 rustc_no_implicit_autorefs,
1285836 "`#[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"
1286837 ),
1287838 rustc_attr!(
1288 rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
839 rustc_coherence_is_core,
1289840 "`#![rustc_coherence_is_core]` allows inherent methods on builtin types, only intended to be used in `core`"
1290841 ),
1291842 rustc_attr!(
1292 rustc_coinductive, AttributeType::Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
843 rustc_coinductive,
1293844 "`#[rustc_coinductive]` changes a trait to be coinductive, allowing cycles in the trait solver"
1294845 ),
1295846 rustc_attr!(
1296 rustc_allow_incoherent_impl, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
847 rustc_allow_incoherent_impl,
1297848 "`#[rustc_allow_incoherent_impl]` has to be added to all impl items of an incoherent inherent impl"
1298849 ),
1299850 rustc_attr!(
1300 rustc_preserve_ub_checks, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
851 rustc_preserve_ub_checks,
1301852 "`#![rustc_preserve_ub_checks]` prevents the designated crate from evaluating whether UB checks are enabled when optimizing MIR",
1302853 ),
1303854 rustc_attr!(
1304855 rustc_deny_explicit_impl,
1305 AttributeType::Normal,
1306 template!(Word),
1307 ErrorFollowing,
1308 EncodeCrossCrate::No,
1309856 "`#[rustc_deny_explicit_impl]` enforces that a trait can have no user-provided impls"
1310857 ),
1311858 rustc_attr!(
1312859 rustc_dyn_incompatible_trait,
1313 AttributeType::Normal,
1314 template!(Word),
1315 ErrorFollowing,
1316 EncodeCrossCrate::No,
1317860 "`#[rustc_dyn_incompatible_trait]` marks a trait as dyn-incompatible, \
1318861 even if it otherwise satisfies the requirements to be dyn-compatible."
1319862 ),
1320863 rustc_attr!(
1321 rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word),
1322 ErrorFollowing, EncodeCrossCrate::Yes,
864 rustc_has_incoherent_inherent_impls,
1323865 "`#[rustc_has_incoherent_inherent_impls]` allows the addition of incoherent inherent impls for \
1324866 the given type by annotating all impl items with `#[rustc_allow_incoherent_impl]`"
1325867 ),
1326868 rustc_attr!(
1327 rustc_non_const_trait_method, AttributeType::Normal, template!(Word),
1328 ErrorFollowing, EncodeCrossCrate::No,
869 rustc_non_const_trait_method,
1329870 "`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \
1330871 as non-const to allow large traits an easier transition to const"
1331872 ),
1332873
1333874 BuiltinAttribute {
1334875 name: sym::rustc_diagnostic_item,
1335 // FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`.
1336 encode_cross_crate: EncodeCrossCrate::Yes,
1337 type_: Normal,
1338876 safety: AttributeSafety::Normal,
1339 template: template!(NameValueStr: "name"),
1340 duplicates: ErrorFollowing,
1341877 gate: Gated {
1342878 feature: sym::rustc_attrs,
1343879 message: "use of an internal attribute",
......@@ -1348,80 +884,75 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
1348884 },
1349885 gated!(
1350886 // Used in resolve:
1351 prelude_import, Normal, template!(Word), WarnFollowing,
1352 EncodeCrossCrate::No, "`#[prelude_import]` is for use by rustc only",
887 prelude_import,
888 "`#[prelude_import]` is for use by rustc only",
1353889 ),
1354890 gated!(
1355 rustc_paren_sugar, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
891 rustc_paren_sugar,
1356892 unboxed_closures, "unboxed_closures are still evolving",
1357893 ),
1358894 rustc_attr!(
1359 rustc_inherit_overflow_checks, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
895 rustc_inherit_overflow_checks,
1360896 "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
1361897 overflow checking behavior of several functions in the standard library that are inlined \
1362898 across crates",
1363899 ),
1364900 rustc_attr!(
1365 rustc_reservation_impl, Normal,
1366 template!(NameValueStr: "reservation message"), ErrorFollowing, EncodeCrossCrate::Yes,
901 rustc_reservation_impl,
1367902 "the `#[rustc_reservation_impl]` attribute is internally used \
1368903 for reserving `impl<T> From<!> for T` as part of the effort to stabilize `!`"
1369904 ),
1370905 rustc_attr!(
1371 rustc_test_marker, Normal, template!(NameValueStr: "name"), WarnFollowing,
1372 EncodeCrossCrate::No, "the `#[rustc_test_marker]` attribute is used internally to track tests",
906 rustc_test_marker,
907 "the `#[rustc_test_marker]` attribute is used internally to track tests",
1373908 ),
1374909 rustc_attr!(
1375 rustc_unsafe_specialization_marker, Normal, template!(Word),
1376 WarnFollowing, EncodeCrossCrate::No,
910 rustc_unsafe_specialization_marker,
1377911 "the `#[rustc_unsafe_specialization_marker]` attribute is used to check specializations"
1378912 ),
1379913 rustc_attr!(
1380 rustc_specialization_trait, Normal, template!(Word),
1381 WarnFollowing, EncodeCrossCrate::No,
914 rustc_specialization_trait,
1382915 "the `#[rustc_specialization_trait]` attribute is used to check specializations"
1383916 ),
1384917 rustc_attr!(
1385 rustc_main, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
918 rustc_main,
1386919 "the `#[rustc_main]` attribute is used internally to specify test entry point function",
1387920 ),
1388921 rustc_attr!(
1389 rustc_skip_during_method_dispatch, Normal, template!(List: &["array, boxed_slice"]), ErrorFollowing,
1390 EncodeCrossCrate::No,
922 rustc_skip_during_method_dispatch,
1391923 "the `#[rustc_skip_during_method_dispatch]` attribute is used to exclude a trait \
1392924 from method dispatch when the receiver is of the following type, for compatibility in \
1393925 editions < 2021 (array) or editions < 2024 (boxed_slice)"
1394926 ),
1395927 rustc_attr!(
1396 rustc_must_implement_one_of, Normal, template!(List: &["function1, function2, ..."]),
1397 ErrorFollowing, EncodeCrossCrate::No,
928 rustc_must_implement_one_of,
1398929 "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \
1399930 definition of a trait. Its syntax and semantics are highly experimental and will be \
1400931 subject to change before stabilization",
1401932 ),
1402933 rustc_attr!(
1403 rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
1404 EncodeCrossCrate::Yes, "the `#[rustc_doc_primitive]` attribute is used by the standard library \
934 rustc_doc_primitive,
935 "the `#[rustc_doc_primitive]` attribute is used by the standard library \
1405936 to provide a way to generate documentation for primitive types",
1406937 ),
1407938 gated!(
1408 rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
939 rustc_intrinsic, intrinsics,
1409940 "the `#[rustc_intrinsic]` attribute is used to declare intrinsics as function items",
1410941 ),
1411942 rustc_attr!(
1412 rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
943 rustc_no_mir_inline,
1413944 "`#[rustc_no_mir_inline]` prevents the MIR inliner from inlining a function while not affecting codegen"
1414945 ),
1415946 rustc_attr!(
1416 rustc_force_inline, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing, EncodeCrossCrate::Yes,
947 rustc_force_inline,
1417948 "`#[rustc_force_inline]` forces a free function to be inlined"
1418949 ),
1419950 rustc_attr!(
1420 rustc_scalable_vector, Normal, template!(List: &["count"]), WarnFollowing, EncodeCrossCrate::Yes,
951 rustc_scalable_vector,
1421952 "`#[rustc_scalable_vector]` defines a scalable vector type"
1422953 ),
1423954 rustc_attr!(
1424 rustc_must_match_exhaustively, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
955 rustc_must_match_exhaustively,
1425956 "enums with `#[rustc_must_match_exhaustively]` must be matched on with a match block that mentions all variants explicitly"
1426957 ),
1427958
......@@ -1429,134 +960,99 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
1429960 // Internal attributes, Testing:
1430961 // ==========================================================================
1431962
1432 rustc_attr!(TEST, rustc_effective_visibility, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes),
963 rustc_attr!(TEST, rustc_effective_visibility),
1433964 rustc_attr!(
1434 TEST, rustc_dump_inferred_outlives, Normal, template!(Word),
1435 WarnFollowing, EncodeCrossCrate::No
965 TEST, rustc_dump_inferred_outlives,
1436966 ),
1437967 rustc_attr!(
1438 TEST, rustc_capture_analysis, Normal, template!(Word),
1439 WarnFollowing, EncodeCrossCrate::No
968 TEST, rustc_capture_analysis,
1440969 ),
1441970 rustc_attr!(
1442 TEST, rustc_insignificant_dtor, Normal, template!(Word),
1443 WarnFollowing, EncodeCrossCrate::Yes
971 TEST, rustc_insignificant_dtor,
1444972 ),
1445973 rustc_attr!(
1446 TEST, rustc_no_implicit_bounds, CrateLevel, template!(Word),
1447 WarnFollowing, EncodeCrossCrate::No
974 TEST, rustc_no_implicit_bounds,
1448975 ),
1449976 rustc_attr!(
1450 TEST, rustc_strict_coherence, Normal, template!(Word),
1451 WarnFollowing, EncodeCrossCrate::Yes
977 TEST, rustc_strict_coherence,
1452978 ),
1453979 rustc_attr!(
1454 TEST, rustc_dump_variances, Normal, template!(Word),
1455 WarnFollowing, EncodeCrossCrate::No
980 TEST, rustc_dump_variances,
1456981 ),
1457982 rustc_attr!(
1458 TEST, rustc_dump_variances_of_opaques, Normal, template!(Word),
1459 WarnFollowing, EncodeCrossCrate::No
983 TEST, rustc_dump_variances_of_opaques,
1460984 ),
1461985 rustc_attr!(
1462 TEST, rustc_dump_hidden_type_of_opaques, Normal, template!(Word),
1463 WarnFollowing, EncodeCrossCrate::No
986 TEST, rustc_dump_hidden_type_of_opaques,
1464987 ),
1465988 rustc_attr!(
1466 TEST, rustc_dump_layout, Normal, template!(List: &["field1, field2, ..."]),
1467 WarnFollowing, EncodeCrossCrate::Yes
989 TEST, rustc_dump_layout,
1468990 ),
1469991 rustc_attr!(
1470 TEST, rustc_abi, Normal, template!(List: &["field1, field2, ..."]),
1471 WarnFollowing, EncodeCrossCrate::No
992 TEST, rustc_abi,
1472993 ),
1473994 rustc_attr!(
1474 TEST, rustc_regions, Normal, template!(Word),
1475 WarnFollowing, EncodeCrossCrate::No
995 TEST, rustc_regions,
1476996 ),
1477997 rustc_attr!(
1478 TEST, rustc_delayed_bug_from_inside_query, Normal,
1479 template!(Word),
1480 WarnFollowing, EncodeCrossCrate::No
998 TEST, rustc_delayed_bug_from_inside_query,
1481999 ),
14821000 rustc_attr!(
1483 TEST, rustc_dump_user_args, Normal, template!(Word),
1484 WarnFollowing, EncodeCrossCrate::No
1001 TEST, rustc_dump_user_args,
14851002 ),
14861003 rustc_attr!(
1487 TEST, rustc_evaluate_where_clauses, Normal, template!(Word), WarnFollowing,
1488 EncodeCrossCrate::Yes
1004 TEST, rustc_evaluate_where_clauses,
14891005 ),
14901006 rustc_attr!(
1491 TEST, rustc_if_this_changed, Normal, template!(Word, List: &["DepNode"]), DuplicatesOk,
1492 EncodeCrossCrate::No
1007 TEST, rustc_if_this_changed,
14931008 ),
14941009 rustc_attr!(
1495 TEST, rustc_then_this_would_need, Normal, template!(List: &["DepNode"]), DuplicatesOk,
1496 EncodeCrossCrate::No
1010 TEST, rustc_then_this_would_need,
14971011 ),
14981012 rustc_attr!(
1499 TEST, rustc_clean, Normal,
1500 template!(List: &[r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#]),
1501 DuplicatesOk, EncodeCrossCrate::No
1013 TEST, rustc_clean,
15021014 ),
15031015 rustc_attr!(
1504 TEST, rustc_partition_reused, Normal,
1505 template!(List: &[r#"cfg = "...", module = "...""#]), DuplicatesOk, EncodeCrossCrate::No
1016 TEST, rustc_partition_reused,
15061017 ),
15071018 rustc_attr!(
1508 TEST, rustc_partition_codegened, Normal,
1509 template!(List: &[r#"cfg = "...", module = "...""#]), DuplicatesOk, EncodeCrossCrate::No
1019 TEST, rustc_partition_codegened,
15101020 ),
15111021 rustc_attr!(
1512 TEST, rustc_expected_cgu_reuse, Normal,
1513 template!(List: &[r#"cfg = "...", module = "...", kind = "...""#]), DuplicatesOk,
1514 EncodeCrossCrate::No
1022 TEST, rustc_expected_cgu_reuse,
15151023 ),
15161024 rustc_attr!(
1517 TEST, rustc_dump_symbol_name, Normal, template!(Word),
1518 WarnFollowing, EncodeCrossCrate::No
1025 TEST, rustc_dump_symbol_name,
15191026 ),
15201027 rustc_attr!(
1521 TEST, rustc_dump_def_path, Normal, template!(Word),
1522 WarnFollowing, EncodeCrossCrate::No
1028 TEST, rustc_dump_def_path,
15231029 ),
15241030 rustc_attr!(
1525 TEST, rustc_mir, Normal, template!(List: &["arg1, arg2, ..."]),
1526 DuplicatesOk, EncodeCrossCrate::Yes
1031 TEST, rustc_mir,
15271032 ),
15281033 gated!(
1529 custom_mir, Normal, template!(List: &[r#"dialect = "...", phase = "...""#]),
1530 ErrorFollowing, EncodeCrossCrate::No,
1531 "the `#[custom_mir]` attribute is just used for the Rust test suite",
1034 custom_mir, "the `#[custom_mir]` attribute is just used for the Rust test suite",
15321035 ),
15331036 rustc_attr!(
1534 TEST, rustc_dump_item_bounds, Normal, template!(Word),
1535 WarnFollowing, EncodeCrossCrate::No
1037 TEST, rustc_dump_item_bounds,
15361038 ),
15371039 rustc_attr!(
1538 TEST, rustc_dump_predicates, Normal, template!(Word),
1539 WarnFollowing, EncodeCrossCrate::No
1040 TEST, rustc_dump_predicates,
15401041 ),
15411042 rustc_attr!(
1542 TEST, rustc_dump_def_parents, Normal, template!(Word),
1543 WarnFollowing, EncodeCrossCrate::No
1043 TEST, rustc_dump_def_parents,
15441044 ),
15451045 rustc_attr!(
1546 TEST, rustc_dump_object_lifetime_defaults, Normal, template!(Word),
1547 WarnFollowing, EncodeCrossCrate::No
1046 TEST, rustc_dump_object_lifetime_defaults,
15481047 ),
15491048 rustc_attr!(
1550 TEST, rustc_dump_vtable, Normal, template!(Word),
1551 WarnFollowing, EncodeCrossCrate::No
1049 TEST, rustc_dump_vtable,
15521050 ),
15531051 rustc_attr!(
1554 TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/),
1555 DuplicatesOk, EncodeCrossCrate::No
1052 TEST, rustc_dummy,
15561053 ),
15571054 rustc_attr!(
1558 TEST, pattern_complexity_limit, CrateLevel, template!(NameValueStr: "N"),
1559 ErrorFollowing, EncodeCrossCrate::No,
1055 TEST, pattern_complexity_limit,
15601056 ),
15611057];
15621058
......@@ -1564,24 +1060,6 @@ pub fn is_builtin_attr_name(name: Symbol) -> bool {
15641060 BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
15651061}
15661062
1567/// Whether this builtin attribute is encoded cross crate.
1568/// This means it can be used cross crate.
1569pub fn encode_cross_crate(name: Symbol) -> bool {
1570 if let Some(attr) = BUILTIN_ATTRIBUTE_MAP.get(&name) {
1571 attr.encode_cross_crate == EncodeCrossCrate::Yes
1572 } else {
1573 true
1574 }
1575}
1576
1577pub fn is_valid_for_get_attr(name: Symbol) -> bool {
1578 BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| match attr.duplicates {
1579 WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
1580 | FutureWarnPreceding => true,
1581 DuplicatesOk | WarnFollowingWordOnly => false,
1582 })
1583}
1584
15851063pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
15861064 LazyLock::new(|| {
15871065 let mut map = FxHashMap::default();
......@@ -1592,13 +1070,3 @@ pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>>
15921070 }
15931071 map
15941072 });
1595
1596pub fn is_stable_diagnostic_attribute(sym: Symbol, features: &Features) -> bool {
1597 match sym {
1598 sym::on_unimplemented | sym::do_not_recommend => true,
1599 sym::on_const => features.diagnostic_on_const(),
1600 sym::on_move => features.diagnostic_on_move(),
1601 sym::on_unknown => features.diagnostic_on_unknown(),
1602 _ => false,
1603 }
1604}
compiler/rustc_feature/src/lib.rs+2-4
......@@ -129,10 +129,8 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZero<u
129129
130130pub use accepted::ACCEPTED_LANG_FEATURES;
131131pub use builtin_attrs::{
132 AttrSuggestionStyle, AttributeDuplicates, AttributeGate, AttributeSafety, AttributeTemplate,
133 AttributeType, BUILTIN_ATTRIBUTE_MAP, BUILTIN_ATTRIBUTES, BuiltinAttribute, GatedCfg,
134 encode_cross_crate, find_gated_cfg, is_builtin_attr_name, is_stable_diagnostic_attribute,
135 is_valid_for_get_attr,
132 AttrSuggestionStyle, AttributeGate, AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP,
133 BUILTIN_ATTRIBUTES, BuiltinAttribute, GatedCfg, find_gated_cfg, is_builtin_attr_name,
136134};
137135pub use removed::REMOVED_LANG_FEATURES;
138136pub use unstable::{
compiler/rustc_metadata/src/rmeta/encoder.rs+5-9
......@@ -10,7 +10,6 @@ use rustc_data_structures::memmap::{Mmap, MmapMut};
1010use rustc_data_structures::sync::{par_for_each_in, par_join};
1111use rustc_data_structures::temp_dir::MaybeTempDir;
1212use rustc_data_structures::thousands::usize_with_underscores;
13use rustc_feature::Features;
1413use rustc_hir as hir;
1514use rustc_hir::attrs::{AttributeKind, EncodeCrossCrate};
1615use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId, LocalDefIdSet};
......@@ -846,10 +845,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
846845 }
847846}
848847
849struct AnalyzeAttrState<'a> {
848struct AnalyzeAttrState {
850849 is_exported: bool,
851850 is_doc_hidden: bool,
852 features: &'a Features,
853851}
854852
855853/// Returns whether an attribute needs to be recorded in metadata, that is, if it's usable and
......@@ -862,16 +860,17 @@ struct AnalyzeAttrState<'a> {
862860/// visibility: this is a piece of data that can be computed once per defid, and not once per
863861/// attribute. Some attributes would only be usable downstream if they are public.
864862#[inline]
865fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState<'_>) -> bool {
863fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState) -> bool {
866864 let mut should_encode = false;
867865 if let hir::Attribute::Parsed(p) = attr
868866 && p.encode_cross_crate() == EncodeCrossCrate::No
869867 {
870868 // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates.
871869 } else if let Some(name) = attr.name()
872 && !rustc_feature::encode_cross_crate(name)
870 && [sym::warn, sym::allow, sym::expect, sym::forbid, sym::deny].contains(&name)
873871 {
874 // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates.
872 // Lint attributes don't need to be encoded for downstream crates.
873 // FIXME remove this when #152369 is re-merged
875874 } else if let hir::Attribute::Parsed(AttributeKind::DocComment { .. }) = attr {
876875 // We keep all doc comments reachable to rustdoc because they might be "imported" into
877876 // downstream crates if they use `#[doc(inline)]` to copy an item's documentation into
......@@ -884,8 +883,6 @@ fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState<'_>) -> bool
884883 if d.hidden.is_some() {
885884 state.is_doc_hidden = true;
886885 }
887 } else if let &[sym::diagnostic, seg] = &*attr.path() {
888 should_encode = rustc_feature::is_stable_diagnostic_attribute(seg, state.features);
889886 } else {
890887 should_encode = true;
891888 }
......@@ -1401,7 +1398,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14011398 let mut state = AnalyzeAttrState {
14021399 is_exported: tcx.effective_visibilities(()).is_exported(def_id),
14031400 is_doc_hidden: false,
1404 features: &tcx.features(),
14051401 };
14061402 let attr_iter = tcx
14071403 .hir_attrs(tcx.local_def_id_to_hir_id(def_id))
compiler/rustc_middle/src/ty/mod.rs-23
......@@ -1736,29 +1736,6 @@ impl<'tcx> TyCtxt<'tcx> {
17361736 }
17371737 }
17381738
1739 #[deprecated = "Though there are valid usecases for this method, especially when your attribute is not a parsed attribute, usually you want to call rustc_hir::find_attr! instead."]
1740 pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx hir::Attribute> {
1741 if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
1742 let did: DefId = did.into();
1743 bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
1744 } else {
1745 #[allow(deprecated)]
1746 self.get_attrs(did, attr).next()
1747 }
1748 }
1749
1750 /// Determines whether an item is annotated with an attribute.
1751 #[deprecated = "Though there are valid usecases for this method, especially when your attribute is not a parsed attribute, usually you want to call rustc_hir::find_attr! instead."]
1752 pub fn has_attr(self, did: impl Into<DefId>, attr: Symbol) -> bool {
1753 #[allow(deprecated)]
1754 self.get_attrs(did, attr).next().is_some()
1755 }
1756
1757 /// Determines whether an item is annotated with a multi-segment attribute
1758 pub fn has_attrs_with_path(self, did: impl Into<DefId>, attrs: &[Symbol]) -> bool {
1759 self.get_attrs_by_path(did.into(), attrs).next().is_some()
1760 }
1761
17621739 /// Returns `true` if this is an `auto trait`.
17631740 pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
17641741 self.trait_def(trait_def_id).has_auto_impl
compiler/rustc_passes/src/check_attr.rs+1-124
......@@ -6,17 +6,15 @@
66//! item.
77
88use std::cell::Cell;
9use std::collections::hash_map::Entry;
109use std::slice;
1110
1211use rustc_abi::ExternAbi;
1312use rustc_ast::{AttrStyle, MetaItemKind, ast};
1413use rustc_attr_parsing::{AttributeParser, Late};
15use rustc_data_structures::fx::FxHashMap;
1614use rustc_data_structures::thin_vec::ThinVec;
1715use rustc_data_structures::unord::UnordMap;
1816use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, msg};
19use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
17use rustc_feature::BUILTIN_ATTRIBUTE_MAP;
2018use rustc_hir::attrs::diagnostic::Directive;
2119use rustc_hir::attrs::{
2220 AttributeKind, DocAttribute, DocInline, EiiDecl, EiiImpl, EiiImplResolution, InlineAttr,
......@@ -145,7 +143,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
145143 target: Target,
146144 item: Option<ItemLike<'_>>,
147145 ) {
148 let mut seen = FxHashMap::default();
149146 let attrs = self.tcx.hir_attrs(hir_id);
150147 for attr in attrs {
151148 let mut style = None;
......@@ -425,65 +422,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
425422 }
426423 }
427424
428 if hir_id != CRATE_HIR_ID {
429 match attr {
430 Attribute::Parsed(_) => { /* Already validated. */ }
431 Attribute::Unparsed(attr) => {
432 // FIXME(jdonszelmann): remove once all crate-level attrs are parsed and caught by
433 // the above
434 if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) =
435 attr.path
436 .segments
437 .first()
438 .and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name))
439 {
440 match attr.style {
441 ast::AttrStyle::Outer => {
442 let attr_span = attr.span;
443 let bang_position = self
444 .tcx
445 .sess
446 .source_map()
447 .span_until_char(attr_span, '[')
448 .shrink_to_hi();
449
450 self.tcx.emit_node_span_lint(
451 UNUSED_ATTRIBUTES,
452 hir_id,
453 attr.span,
454 errors::OuterCrateLevelAttr {
455 suggestion: errors::OuterCrateLevelAttrSuggestion {
456 bang_position,
457 },
458 },
459 )
460 }
461 ast::AttrStyle::Inner => self.tcx.emit_node_span_lint(
462 UNUSED_ATTRIBUTES,
463 hir_id,
464 attr.span,
465 errors::InnerCrateLevelAttr,
466 ),
467 }
468 }
469 }
470 }
471 }
472
473 if let Attribute::Unparsed(unparsed_attr) = attr
474 && let Some(BuiltinAttribute { duplicates, .. }) =
475 attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name))
476 {
477 check_duplicates(
478 self.tcx,
479 unparsed_attr.span,
480 attr,
481 hir_id,
482 *duplicates,
483 &mut seen,
484 );
485 }
486
487425 self.check_unused_attribute(hir_id, attr, style)
488426 }
489427
......@@ -2041,67 +1979,6 @@ pub(crate) fn provide(providers: &mut Providers) {
20411979 *providers = Providers { check_mod_attrs, ..*providers };
20421980}
20431981
2044// FIXME(jdonszelmann): remove, check during parsing
2045fn check_duplicates(
2046 tcx: TyCtxt<'_>,
2047 attr_span: Span,
2048 attr: &Attribute,
2049 hir_id: HirId,
2050 duplicates: AttributeDuplicates,
2051 seen: &mut FxHashMap<Symbol, Span>,
2052) {
2053 use AttributeDuplicates::*;
2054 if matches!(duplicates, WarnFollowingWordOnly) && !attr.is_word() {
2055 return;
2056 }
2057 let attr_name = attr.name().unwrap();
2058 match duplicates {
2059 DuplicatesOk => {}
2060 WarnFollowing | FutureWarnFollowing | WarnFollowingWordOnly | FutureWarnPreceding => {
2061 match seen.entry(attr_name) {
2062 Entry::Occupied(mut entry) => {
2063 let (this, other) = if matches!(duplicates, FutureWarnPreceding) {
2064 let to_remove = entry.insert(attr_span);
2065 (to_remove, attr_span)
2066 } else {
2067 (attr_span, *entry.get())
2068 };
2069 tcx.emit_node_span_lint(
2070 UNUSED_ATTRIBUTES,
2071 hir_id,
2072 this,
2073 errors::UnusedDuplicate {
2074 this,
2075 other,
2076 warning: matches!(
2077 duplicates,
2078 FutureWarnFollowing | FutureWarnPreceding
2079 ),
2080 },
2081 );
2082 }
2083 Entry::Vacant(entry) => {
2084 entry.insert(attr_span);
2085 }
2086 }
2087 }
2088 ErrorFollowing | ErrorPreceding => match seen.entry(attr_name) {
2089 Entry::Occupied(mut entry) => {
2090 let (this, other) = if matches!(duplicates, ErrorPreceding) {
2091 let to_remove = entry.insert(attr_span);
2092 (to_remove, attr_span)
2093 } else {
2094 (attr_span, *entry.get())
2095 };
2096 tcx.dcx().emit_err(errors::UnusedMultiple { this, other, name: attr_name });
2097 }
2098 Entry::Vacant(entry) => {
2099 entry.insert(attr_span);
2100 }
2101 },
2102 }
2103}
2104
21051982fn doc_fake_variadic_is_allowed_self_ty(self_ty: &hir::Ty<'_>) -> bool {
21061983 matches!(&self_ty.kind, hir::TyKind::Tup([_]))
21071984 || if let hir::TyKind::FnPtr(fn_ptr_ty) = &self_ty.kind {
compiler/rustc_passes/src/errors.rs-24
......@@ -328,30 +328,6 @@ pub(crate) struct InvalidMayDangle {
328328 pub attr_span: Span,
329329}
330330
331#[derive(Diagnostic)]
332#[diag("unused attribute")]
333pub(crate) struct UnusedDuplicate {
334 #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")]
335 pub this: Span,
336 #[note("attribute also specified here")]
337 pub other: Span,
338 #[warning(
339 "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!"
340 )]
341 pub warning: bool,
342}
343
344#[derive(Diagnostic)]
345#[diag("multiple `{$name}` attributes")]
346pub(crate) struct UnusedMultiple {
347 #[primary_span]
348 #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")]
349 pub this: Span,
350 #[note("attribute also specified here")]
351 pub other: Span,
352 pub name: Symbol,
353}
354
355331#[derive(Diagnostic)]
356332#[diag("this `#[deprecated]` annotation has no effect")]
357333pub(crate) struct DeprecatedAnnotationHasNoEffect {
src/tools/clippy/clippy_lints/src/cognitive_complexity.rs+1-1
......@@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity {
145145 def_id: LocalDefId,
146146 ) {
147147 #[allow(deprecated)]
148 if !cx.tcx.has_attr(def_id, sym::test) {
148 if !cx.tcx.get_attrs(def_id, sym::test).next().is_some() {
149149 let expr = if kind.asyncness().is_async() {
150150 match get_async_fn_body(cx.tcx, body) {
151151 Some(b) => b,
src/tools/clippy/clippy_utils/src/lib.rs+1-2
......@@ -2400,8 +2400,7 @@ pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
24002400 if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
24012401 && let Res::Def(_, def_id) = path.res
24022402 {
2403 #[allow(deprecated)]
2404 return cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr);
2403 return find_attr!(cx.tcx, def_id, CfgTrace(..) | CfgAttrTrace);
24052404 }
24062405 false
24072406}