rustc_hir/attrs/
data_structures.rs

1use std::borrow::Cow;
2use std::path::PathBuf;
3
4pub use ReprAttr::*;
5use rustc_abi::Align;
6use rustc_ast::token::CommentKind;
7use rustc_ast::{AttrStyle, ast};
8use rustc_error_messages::{DiagArgValue, IntoDiagArg};
9use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
10use rustc_span::def_id::DefId;
11use rustc_span::hygiene::Transparency;
12use rustc_span::{Ident, Span, Symbol};
13pub use rustc_target::spec::SanitizerSet;
14use thin_vec::ThinVec;
15
16use crate::attrs::pretty_printing::PrintAttribute;
17use crate::{DefaultBodyStability, PartialConstStability, RustcVersion, Stability};
18
19#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)]
20pub enum InlineAttr {
21    None,
22    Hint,
23    Always,
24    Never,
25    /// `#[rustc_force_inline]` forces inlining to happen in the MIR inliner - it reports an error
26    /// if the inlining cannot happen. It is limited to only free functions so that the calls
27    /// can always be resolved.
28    Force {
29        attr_span: Span,
30        reason: Option<Symbol>,
31    },
32}
33
34impl InlineAttr {
35    pub fn always(&self) -> bool {
36        match self {
37            InlineAttr::Always | InlineAttr::Force { .. } => true,
38            InlineAttr::None | InlineAttr::Hint | InlineAttr::Never => false,
39        }
40    }
41}
42
43#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)]
44pub enum InstructionSetAttr {
45    ArmA32,
46    ArmT32,
47}
48
49#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, PrintAttribute)]
50#[derive(Encodable, Decodable, HashStable_Generic)]
51pub enum OptimizeAttr {
52    /// No `#[optimize(..)]` attribute
53    #[default]
54    Default,
55    /// `#[optimize(none)]`
56    DoNotOptimize,
57    /// `#[optimize(speed)]`
58    Speed,
59    /// `#[optimize(size)]`
60    Size,
61}
62
63impl OptimizeAttr {
64    pub fn do_not_optimize(&self) -> bool {
65        matches!(self, Self::DoNotOptimize)
66    }
67}
68
69#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic, PrintAttribute)]
70pub enum ReprAttr {
71    ReprInt(IntType),
72    ReprRust,
73    ReprC,
74    ReprPacked(Align),
75    ReprSimd,
76    ReprTransparent,
77    ReprAlign(Align),
78}
79
80pub enum TransparencyError {
81    UnknownTransparency(Symbol, Span),
82    MultipleTransparencyAttrs(Span, Span),
83}
84
85#[derive(Eq, PartialEq, Debug, Copy, Clone)]
86#[derive(Encodable, Decodable, HashStable_Generic, PrintAttribute)]
87pub enum IntType {
88    SignedInt(ast::IntTy),
89    UnsignedInt(ast::UintTy),
90}
91
92#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
93pub struct Deprecation {
94    pub since: DeprecatedSince,
95    /// The note to issue a reason.
96    pub note: Option<Symbol>,
97    /// A text snippet used to completely replace any use of the deprecated item in an expression.
98    ///
99    /// This is currently unstable.
100    pub suggestion: Option<Symbol>,
101}
102
103/// Release in which an API is deprecated.
104#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
105pub enum DeprecatedSince {
106    RustcVersion(RustcVersion),
107    /// Deprecated in the future ("to be determined").
108    Future,
109    /// `feature(staged_api)` is off. Deprecation versions outside the standard
110    /// library are allowed to be arbitrary strings, for better or worse.
111    NonStandard(Symbol),
112    /// Deprecation version is unspecified but optional.
113    Unspecified,
114    /// Failed to parse a deprecation version, or the deprecation version is
115    /// unspecified and required. An error has already been emitted.
116    Err,
117}
118
119/// Successfully-parsed value of a `#[coverage(..)]` attribute.
120#[derive(Copy, Debug, Eq, PartialEq, Encodable, Decodable, Clone)]
121#[derive(HashStable_Generic, PrintAttribute)]
122pub enum CoverageAttrKind {
123    On,
124    Off,
125}
126
127impl Deprecation {
128    /// Whether an item marked with #[deprecated(since = "X")] is currently
129    /// deprecated (i.e., whether X is not greater than the current rustc
130    /// version).
131    pub fn is_in_effect(&self) -> bool {
132        match self.since {
133            DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT,
134            DeprecatedSince::Future => false,
135            // The `since` field doesn't have semantic purpose without `#![staged_api]`.
136            DeprecatedSince::NonStandard(_) => true,
137            // Assume deprecation is in effect if "since" field is absent or invalid.
138            DeprecatedSince::Unspecified | DeprecatedSince::Err => true,
139        }
140    }
141
142    pub fn is_since_rustc_version(&self) -> bool {
143        matches!(self.since, DeprecatedSince::RustcVersion(_))
144    }
145}
146
147/// There are three valid forms of the attribute:
148/// `#[used]`, which is semantically equivalent to `#[used(linker)]` except that the latter is currently unstable.
149/// `#[used(compiler)]`
150/// `#[used(linker)]`
151#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
152#[derive(HashStable_Generic, PrintAttribute)]
153pub enum UsedBy {
154    Compiler,
155    Linker,
156}
157
158#[derive(Encodable, Decodable, Clone, Debug, PartialEq, Eq, Hash)]
159#[derive(HashStable_Generic, PrintAttribute)]
160pub enum MacroUseArgs {
161    UseAll,
162    UseSpecific(ThinVec<Ident>),
163}
164
165impl Default for MacroUseArgs {
166    fn default() -> Self {
167        Self::UseSpecific(ThinVec::new())
168    }
169}
170
171#[derive(Debug, Clone, Encodable, Decodable, HashStable_Generic)]
172pub struct StrippedCfgItem<ModId = DefId> {
173    pub parent_module: ModId,
174    pub ident: Ident,
175    pub cfg: (CfgEntry, Span),
176}
177
178impl<ModId> StrippedCfgItem<ModId> {
179    pub fn map_mod_id<New>(self, f: impl FnOnce(ModId) -> New) -> StrippedCfgItem<New> {
180        StrippedCfgItem { parent_module: f(self.parent_module), ident: self.ident, cfg: self.cfg }
181    }
182}
183
184#[derive(Encodable, Decodable, Clone, Debug, PartialEq, Eq, Hash)]
185#[derive(HashStable_Generic, PrintAttribute)]
186pub enum CfgEntry {
187    All(ThinVec<CfgEntry>, Span),
188    Any(ThinVec<CfgEntry>, Span),
189    Not(Box<CfgEntry>, Span),
190    Bool(bool, Span),
191    NameValue { name: Symbol, name_span: Span, value: Option<(Symbol, Span)>, span: Span },
192    Version(Option<RustcVersion>, Span),
193}
194
195/// Possible values for the `#[linkage]` attribute, allowing to specify the
196/// linkage type for a `MonoItem`.
197///
198/// See <https://llvm.org/docs/LangRef.html#linkage-types> for more details about these variants.
199#[derive(Encodable, Decodable, Clone, Copy, Debug, PartialEq, Eq, Hash)]
200#[derive(HashStable_Generic, PrintAttribute)]
201pub enum Linkage {
202    AvailableExternally,
203    Common,
204    ExternalWeak,
205    External,
206    Internal,
207    LinkOnceAny,
208    LinkOnceODR,
209    WeakAny,
210    WeakODR,
211}
212
213#[derive(Clone, Copy, Decodable, Debug, Encodable, PartialEq)]
214#[derive(HashStable_Generic, PrintAttribute)]
215pub enum MirDialect {
216    Analysis,
217    Built,
218    Runtime,
219}
220
221impl IntoDiagArg for MirDialect {
222    fn into_diag_arg(self, _path: &mut Option<PathBuf>) -> DiagArgValue {
223        let arg = match self {
224            MirDialect::Analysis => "analysis",
225            MirDialect::Built => "built",
226            MirDialect::Runtime => "runtime",
227        };
228        DiagArgValue::Str(Cow::Borrowed(arg))
229    }
230}
231
232#[derive(Clone, Copy, Decodable, Debug, Encodable, PartialEq)]
233#[derive(HashStable_Generic, PrintAttribute)]
234pub enum MirPhase {
235    Initial,
236    PostCleanup,
237    Optimized,
238}
239
240impl IntoDiagArg for MirPhase {
241    fn into_diag_arg(self, _path: &mut Option<PathBuf>) -> DiagArgValue {
242        let arg = match self {
243            MirPhase::Initial => "initial",
244            MirPhase::PostCleanup => "post-cleanup",
245            MirPhase::Optimized => "optimized",
246        };
247        DiagArgValue::Str(Cow::Borrowed(arg))
248    }
249}
250
251/// Different ways that the PE Format can decorate a symbol name.
252/// From <https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type>
253#[derive(
254    Copy,
255    Clone,
256    Debug,
257    Encodable,
258    Decodable,
259    HashStable_Generic,
260    PartialEq,
261    Eq,
262    PrintAttribute
263)]
264pub enum PeImportNameType {
265    /// IMPORT_ORDINAL
266    /// Uses the ordinal (i.e., a number) rather than the name.
267    Ordinal(u16),
268    /// Same as IMPORT_NAME
269    /// Name is decorated with all prefixes and suffixes.
270    Decorated,
271    /// Same as IMPORT_NAME_NOPREFIX
272    /// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept.
273    NoPrefix,
274    /// Same as IMPORT_NAME_UNDECORATE
275    /// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all
276    /// trailing characters) are skipped.
277    Undecorated,
278}
279
280#[derive(
281    Copy,
282    Clone,
283    Debug,
284    PartialEq,
285    Eq,
286    PartialOrd,
287    Ord,
288    Hash,
289    Encodable,
290    Decodable,
291    PrintAttribute
292)]
293#[derive(HashStable_Generic)]
294pub enum NativeLibKind {
295    /// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC)
296    Static {
297        /// Whether to bundle objects from static library into produced rlib
298        bundle: Option<bool>,
299        /// Whether to link static library without throwing any object files away
300        whole_archive: Option<bool>,
301    },
302    /// Dynamic library (e.g. `libfoo.so` on Linux)
303    /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC).
304    Dylib {
305        /// Whether the dynamic library will be linked only if it satisfies some undefined symbols
306        as_needed: Option<bool>,
307    },
308    /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library.
309    /// On Linux, it refers to a generated shared library stub.
310    RawDylib,
311    /// A macOS-specific kind of dynamic libraries.
312    Framework {
313        /// Whether the framework will be linked only if it satisfies some undefined symbols
314        as_needed: Option<bool>,
315    },
316    /// Argument which is passed to linker, relative order with libraries and other arguments
317    /// is preserved
318    LinkArg,
319
320    /// Module imported from WebAssembly
321    WasmImportModule,
322
323    /// The library kind wasn't specified, `Dylib` is currently used as a default.
324    Unspecified,
325}
326
327impl NativeLibKind {
328    pub fn has_modifiers(&self) -> bool {
329        match self {
330            NativeLibKind::Static { bundle, whole_archive } => {
331                bundle.is_some() || whole_archive.is_some()
332            }
333            NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
334                as_needed.is_some()
335            }
336            NativeLibKind::RawDylib
337            | NativeLibKind::Unspecified
338            | NativeLibKind::LinkArg
339            | NativeLibKind::WasmImportModule => false,
340        }
341    }
342
343    pub fn is_statically_included(&self) -> bool {
344        matches!(self, NativeLibKind::Static { .. })
345    }
346
347    pub fn is_dllimport(&self) -> bool {
348        matches!(
349            self,
350            NativeLibKind::Dylib { .. } | NativeLibKind::RawDylib | NativeLibKind::Unspecified
351        )
352    }
353}
354
355#[derive(Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
356pub struct LinkEntry {
357    pub span: Span,
358    pub kind: NativeLibKind,
359    pub name: Symbol,
360    pub cfg: Option<CfgEntry>,
361    pub verbatim: Option<bool>,
362    pub import_name_type: Option<(PeImportNameType, Span)>,
363}
364
365/// Represents parsed *built-in* inert attributes.
366///
367/// ## Overview
368/// These attributes are markers that guide the compilation process and are never expanded into other code.
369/// They persist throughout the compilation phases, from AST to HIR and beyond.
370///
371/// ## Attribute Processing
372/// While attributes are initially parsed by [`rustc_parse`] into [`ast::Attribute`], they still contain raw token streams
373/// because different attributes have different internal structures. This enum represents the final,
374/// fully parsed form of these attributes, where each variant contains all the information and
375/// structure relevant for the specific attribute.
376///
377/// Some attributes can be applied multiple times to the same item, and they are "collapsed" into a single
378/// semantic attribute. For example:
379/// ```rust
380/// #[repr(C)]
381/// #[repr(packed)]
382/// struct S { }
383/// ```
384/// This is equivalent to `#[repr(C, packed)]` and results in a single [`AttributeKind::Repr`] containing
385/// both `C` and `packed` annotations. This collapsing happens during parsing and is reflected in the
386/// data structures defined in this enum.
387///
388/// ## Usage
389/// These parsed attributes are used throughout the compiler to:
390/// - Control code generation (e.g., `#[repr]`)
391/// - Mark API stability (`#[stable]`, `#[unstable]`)
392/// - Provide documentation (`#[doc]`)
393/// - Guide compiler behavior (e.g., `#[allow_internal_unstable]`)
394///
395/// ## Note on Attribute Organization
396/// Some attributes like `InlineAttr`, `OptimizeAttr`, and `InstructionSetAttr` are defined separately
397/// from this enum because they are used in specific compiler phases (like code generation) and don't
398/// need to persist throughout the entire compilation process. They are typically processed and
399/// converted into their final form earlier in the compilation pipeline.
400///
401/// For example:
402/// - `InlineAttr` is used during code generation to control function inlining
403/// - `OptimizeAttr` is used to control optimization levels
404/// - `InstructionSetAttr` is used for target-specific code generation
405///
406/// These attributes are handled by their respective compiler passes in the [`rustc_codegen_ssa`] crate
407/// and don't need to be preserved in the same way as the attributes in this enum.
408///
409/// For more details on attribute parsing, see the [`rustc_attr_parsing`] crate.
410///
411/// [`rustc_parse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
412/// [`rustc_codegen_ssa`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/index.html
413/// [`rustc_attr_parsing`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html
414#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
415pub enum AttributeKind {
416    // tidy-alphabetical-start
417    /// Represents `#[align(N)]`.
418    // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
419    Align { align: Align, span: Span },
420
421    /// Represents `#[rustc_allow_const_fn_unstable]`.
422    AllowConstFnUnstable(ThinVec<Symbol>, Span),
423
424    /// Represents `#[rustc_allow_incoherent_impl]`.
425    AllowIncoherentImpl(Span),
426
427    /// Represents `#[allow_internal_unsafe]`.
428    AllowInternalUnsafe(Span),
429
430    /// Represents `#[allow_internal_unstable]`.
431    AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span),
432
433    /// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
434    AsPtr(Span),
435
436    /// Represents `#[automatically_derived]`
437    AutomaticallyDerived(Span),
438
439    /// Represents `#[rustc_default_body_unstable]`.
440    BodyStability {
441        stability: DefaultBodyStability,
442        /// Span of the `#[rustc_default_body_unstable(...)]` attribute
443        span: Span,
444    },
445
446    /// Represents `#[rustc_coherence_is_core]`.
447    CoherenceIsCore,
448
449    /// Represents `#[rustc_coinductive]`.
450    Coinductive(Span),
451
452    /// Represents `#[cold]`.
453    Cold(Span),
454
455    /// Represents `#[rustc_confusables]`.
456    Confusables {
457        symbols: ThinVec<Symbol>,
458        // FIXME(jdonszelmann): remove when target validation code is moved
459        first_span: Span,
460    },
461
462    /// Represents `#[const_continue]`.
463    ConstContinue(Span),
464
465    /// Represents `#[rustc_const_stable]` and `#[rustc_const_unstable]`.
466    ConstStability {
467        stability: PartialConstStability,
468        /// Span of the `#[rustc_const_stable(...)]` or `#[rustc_const_unstable(...)]` attribute
469        span: Span,
470    },
471
472    /// Represents `#[rustc_const_stable_indirect]`.
473    ConstStabilityIndirect,
474
475    /// Represents `#[const_trait]`.
476    ConstTrait(Span),
477
478    /// Represents `#[coroutine]`.
479    Coroutine(Span),
480
481    /// Represents `#[coverage(..)]`.
482    Coverage(Span, CoverageAttrKind),
483
484    /// Represents `#[crate_name = ...]`
485    CrateName { name: Symbol, name_span: Span, attr_span: Span, style: AttrStyle },
486
487    /// Represents `#[custom_mir]`.
488    CustomMir(Option<(MirDialect, Span)>, Option<(MirPhase, Span)>, Span),
489
490    ///Represents `#[rustc_deny_explicit_impl]`.
491    DenyExplicitImpl(Span),
492
493    /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
494    Deprecation { deprecation: Deprecation, span: Span },
495
496    /// Represents `#[rustc_do_not_implement_via_object]`.
497    DoNotImplementViaObject(Span),
498
499    /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
500    DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },
501
502    /// Represents `#[rustc_dummy]`.
503    Dummy,
504
505    /// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute).
506    ExportName {
507        /// The name to export this item with.
508        /// It may not contain \0 bytes as it will be converted to a null-terminated string.
509        name: Symbol,
510        span: Span,
511    },
512
513    /// Represents `#[export_stable]`.
514    ExportStable,
515
516    /// Represents `#[ffi_const]`.
517    FfiConst(Span),
518
519    /// Represents `#[ffi_pure]`.
520    FfiPure(Span),
521
522    /// Represents `#[fundamental]`.
523    Fundamental,
524
525    /// Represents `#[ignore]`
526    Ignore {
527        span: Span,
528        /// ignore can optionally have a reason: `#[ignore = "reason this is ignored"]`
529        reason: Option<Symbol>,
530    },
531
532    /// Represents `#[inline]` and `#[rustc_force_inline]`.
533    Inline(InlineAttr, Span),
534
535    /// Represents `#[link]`.
536    Link(ThinVec<LinkEntry>, Span),
537
538    /// Represents `#[link_name]`.
539    LinkName { name: Symbol, span: Span },
540
541    /// Represents `#[link_ordinal]`.
542    LinkOrdinal { ordinal: u16, span: Span },
543
544    /// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
545    LinkSection { name: Symbol, span: Span },
546
547    /// Represents `#[linkage]`.
548    Linkage(Linkage, Span),
549
550    /// Represents `#[loop_match]`.
551    LoopMatch(Span),
552
553    /// Represents `#[macro_escape]`.
554    MacroEscape(Span),
555
556    /// Represents `#[rustc_macro_transparency]`.
557    MacroTransparency(Transparency),
558
559    /// Represents `#[macro_use]`.
560    MacroUse { span: Span, arguments: MacroUseArgs },
561
562    /// Represents `#[marker]`.
563    Marker(Span),
564
565    /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html).
566    MayDangle(Span),
567
568    /// Represents `#[must_use]`.
569    MustUse {
570        span: Span,
571        /// must_use can optionally have a reason: `#[must_use = "reason this must be used"]`
572        reason: Option<Symbol>,
573    },
574
575    /// Represents `#[naked]`
576    Naked(Span),
577
578    /// Represents `#[no_implicit_prelude]`
579    NoImplicitPrelude(Span),
580
581    /// Represents `#[no_mangle]`
582    NoMangle(Span),
583
584    /// Represents `#[non_exhaustive]`
585    NonExhaustive(Span),
586
587    /// Represents `#[optimize(size|speed)]`
588    Optimize(OptimizeAttr, Span),
589
590    /// Represents `#[rustc_paren_sugar]`.
591    ParenSugar(Span),
592
593    /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint).
594    PassByValue(Span),
595
596    /// Represents `#[path]`
597    Path(Symbol, Span),
598
599    /// Represents `#[pointee]`
600    Pointee(Span),
601
602    /// Represents `#[proc_macro]`
603    ProcMacro(Span),
604
605    /// Represents `#[proc_macro_attribute]`
606    ProcMacroAttribute(Span),
607
608    /// Represents `#[proc_macro_derive]`
609    ProcMacroDerive { trait_name: Symbol, helper_attrs: ThinVec<Symbol>, span: Span },
610
611    /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint).
612    PubTransparent(Span),
613
614    /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
615    Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
616
617    /// Represents `#[rustc_builtin_macro]`.
618    RustcBuiltinMacro { builtin_name: Option<Symbol>, helper_attrs: ThinVec<Symbol>, span: Span },
619
620    /// Represents `#[rustc_layout_scalar_valid_range_end]`.
621    RustcLayoutScalarValidRangeEnd(Box<u128>, Span),
622
623    /// Represents `#[rustc_layout_scalar_valid_range_start]`.
624    RustcLayoutScalarValidRangeStart(Box<u128>, Span),
625
626    /// Represents `#[rustc_object_lifetime_default]`.
627    RustcObjectLifetimeDefault,
628
629    /// Represents `#[sanitize]`
630    ///
631    /// the on set and off set are distjoint since there's a third option: unset.
632    /// a node may not set the sanitizer setting in which case it inherits from parents.
633    Sanitize { on_set: SanitizerSet, off_set: SanitizerSet, span: Span },
634
635    /// Represents `#[should_panic]`
636    ShouldPanic { reason: Option<Symbol>, span: Span },
637
638    /// Represents `#[rustc_skip_during_method_dispatch]`.
639    SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span },
640
641    /// Represents `#[rustc_specialization_trait]`.
642    SpecializationTrait(Span),
643
644    /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
645    Stability {
646        stability: Stability,
647        /// Span of the attribute.
648        span: Span,
649    },
650
651    /// Represents `#[rustc_std_internal_symbol]`.
652    StdInternalSymbol(Span),
653
654    /// Represents `#[target_feature(enable = "...")]` and
655    /// `#[unsafe(force_target_feature(enable = "...")]`.
656    TargetFeature { features: ThinVec<(Symbol, Span)>, attr_span: Span, was_forced: bool },
657
658    /// Represents `#[track_caller]`
659    TrackCaller(Span),
660
661    /// Represents `#[type_const]`.
662    TypeConst(Span),
663
664    /// Represents `#[rustc_unsafe_specialization_marker]`.
665    UnsafeSpecializationMarker(Span),
666
667    /// Represents `#[unstable_feature_bound]`.
668    UnstableFeatureBound(ThinVec<(Symbol, Span)>),
669
670    /// Represents `#[used]`
671    Used { used_by: UsedBy, span: Span },
672    // tidy-alphabetical-end
673}