rustc_attr_data_structures/
attributes.rs

1use rustc_abi::Align;
2use rustc_ast::token::CommentKind;
3use rustc_ast::{self as ast, AttrStyle};
4use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
5use rustc_span::hygiene::Transparency;
6use rustc_span::{Span, Symbol};
7use thin_vec::ThinVec;
8
9use crate::{DefaultBodyStability, PartialConstStability, PrintAttribute, RustcVersion, Stability};
10
11#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
12pub enum InlineAttr {
13    None,
14    Hint,
15    Always,
16    Never,
17    /// `#[rustc_force_inline]` forces inlining to happen in the MIR inliner - it reports an error
18    /// if the inlining cannot happen. It is limited to only free functions so that the calls
19    /// can always be resolved.
20    Force {
21        attr_span: Span,
22        reason: Option<Symbol>,
23    },
24}
25
26impl InlineAttr {
27    pub fn always(&self) -> bool {
28        match self {
29            InlineAttr::Always | InlineAttr::Force { .. } => true,
30            InlineAttr::None | InlineAttr::Hint | InlineAttr::Never => false,
31        }
32    }
33}
34
35#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)]
36pub enum InstructionSetAttr {
37    ArmA32,
38    ArmT32,
39}
40
41#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic, Default)]
42pub enum OptimizeAttr {
43    /// No `#[optimize(..)]` attribute
44    #[default]
45    Default,
46    /// `#[optimize(none)]`
47    DoNotOptimize,
48    /// `#[optimize(speed)]`
49    Speed,
50    /// `#[optimize(size)]`
51    Size,
52}
53
54impl OptimizeAttr {
55    pub fn do_not_optimize(&self) -> bool {
56        matches!(self, Self::DoNotOptimize)
57    }
58}
59
60#[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic, PrintAttribute)]
61pub enum DiagnosticAttribute {
62    // tidy-alphabetical-start
63    DoNotRecommend,
64    OnUnimplemented,
65    // tidy-alphabetical-end
66}
67
68#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic, PrintAttribute)]
69pub enum ReprAttr {
70    ReprInt(IntType),
71    ReprRust,
72    ReprC,
73    ReprPacked(Align),
74    ReprSimd,
75    ReprTransparent,
76    ReprAlign(Align),
77    // this one is just so we can emit a lint for it
78    ReprEmpty,
79}
80pub use ReprAttr::*;
81
82pub enum TransparencyError {
83    UnknownTransparency(Symbol, Span),
84    MultipleTransparencyAttrs(Span, Span),
85}
86
87#[derive(Eq, PartialEq, Debug, Copy, Clone)]
88#[derive(Encodable, Decodable, HashStable_Generic, PrintAttribute)]
89pub enum IntType {
90    SignedInt(ast::IntTy),
91    UnsignedInt(ast::UintTy),
92}
93
94#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
95pub struct Deprecation {
96    pub since: DeprecatedSince,
97    /// The note to issue a reason.
98    pub note: Option<Symbol>,
99    /// A text snippet used to completely replace any use of the deprecated item in an expression.
100    ///
101    /// This is currently unstable.
102    pub suggestion: Option<Symbol>,
103}
104
105/// Release in which an API is deprecated.
106#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
107pub enum DeprecatedSince {
108    RustcVersion(RustcVersion),
109    /// Deprecated in the future ("to be determined").
110    Future,
111    /// `feature(staged_api)` is off. Deprecation versions outside the standard
112    /// library are allowed to be arbitrary strings, for better or worse.
113    NonStandard(Symbol),
114    /// Deprecation version is unspecified but optional.
115    Unspecified,
116    /// Failed to parse a deprecation version, or the deprecation version is
117    /// unspecified and required. An error has already been emitted.
118    Err,
119}
120
121impl Deprecation {
122    /// Whether an item marked with #[deprecated(since = "X")] is currently
123    /// deprecated (i.e., whether X is not greater than the current rustc
124    /// version).
125    pub fn is_in_effect(&self) -> bool {
126        match self.since {
127            DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT,
128            DeprecatedSince::Future => false,
129            // The `since` field doesn't have semantic purpose without `#![staged_api]`.
130            DeprecatedSince::NonStandard(_) => true,
131            // Assume deprecation is in effect if "since" field is absent or invalid.
132            DeprecatedSince::Unspecified | DeprecatedSince::Err => true,
133        }
134    }
135
136    pub fn is_since_rustc_version(&self) -> bool {
137        matches!(self.since, DeprecatedSince::RustcVersion(_))
138    }
139}
140
141/// Represent parsed, *built in*, inert attributes.
142///
143/// That means attributes that are not actually ever expanded.
144/// For more information on this, see the module docs on the [`rustc_attr_parsing`] crate.
145/// They're instead used as markers, to guide the compilation process in various way in most every stage of the compiler.
146/// These are kept around after the AST, into the HIR and further on.
147///
148/// The word "parsed" could be a little misleading here, because the parser already parses
149/// attributes early on. However, the result, an [`ast::Attribute`]
150/// is only parsed at a high level, still containing a token stream in many cases. That is
151/// because the structure of the contents varies from attribute to attribute.
152/// With a parsed attribute I mean that each attribute is processed individually into a
153/// final structure, which on-site (the place where the attribute is useful for, think the
154/// the place where `must_use` is checked) little to no extra parsing or validating needs to
155/// happen.
156///
157/// For more docs, look in [`rustc_attr_parsing`].
158///
159/// [`rustc_attr_parsing`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html
160#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
161pub enum AttributeKind {
162    // tidy-alphabetical-start
163    AllowConstFnUnstable(ThinVec<Symbol>),
164    AllowInternalUnstable(ThinVec<(Symbol, Span)>),
165    BodyStability {
166        stability: DefaultBodyStability,
167        /// Span of the `#[rustc_default_body_unstable(...)]` attribute
168        span: Span,
169    },
170    Confusables {
171        symbols: ThinVec<Symbol>,
172        // FIXME(jdonszelmann): remove when target validation code is moved
173        first_span: Span,
174    },
175    ConstStability {
176        stability: PartialConstStability,
177        /// Span of the `#[rustc_const_stable(...)]` or `#[rustc_const_unstable(...)]` attribute
178        span: Span,
179    },
180    ConstStabilityIndirect,
181    Deprecation {
182        deprecation: Deprecation,
183        span: Span,
184    },
185    Diagnostic(DiagnosticAttribute),
186    DocComment {
187        style: AttrStyle,
188        kind: CommentKind,
189        span: Span,
190        comment: Symbol,
191    },
192    MacroTransparency(Transparency),
193    Repr(ThinVec<(ReprAttr, Span)>),
194    RustcMacroEdition2021,
195    Stability {
196        stability: Stability,
197        /// Span of the `#[stable(...)]` or `#[unstable(...)]` attribute
198        span: Span,
199    },
200    // tidy-alphabetical-end
201}