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(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic, PrintAttribute)]
61pub enum ReprAttr {
62    ReprInt(IntType),
63    ReprRust,
64    ReprC,
65    ReprPacked(Align),
66    ReprSimd,
67    ReprTransparent,
68    ReprAlign(Align),
69    // this one is just so we can emit a lint for it
70    ReprEmpty,
71}
72pub use ReprAttr::*;
73
74pub enum TransparencyError {
75    UnknownTransparency(Symbol, Span),
76    MultipleTransparencyAttrs(Span, Span),
77}
78
79#[derive(Eq, PartialEq, Debug, Copy, Clone)]
80#[derive(Encodable, Decodable, HashStable_Generic, PrintAttribute)]
81pub enum IntType {
82    SignedInt(ast::IntTy),
83    UnsignedInt(ast::UintTy),
84}
85
86#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
87pub struct Deprecation {
88    pub since: DeprecatedSince,
89    /// The note to issue a reason.
90    pub note: Option<Symbol>,
91    /// A text snippet used to completely replace any use of the deprecated item in an expression.
92    ///
93    /// This is currently unstable.
94    pub suggestion: Option<Symbol>,
95}
96
97/// Release in which an API is deprecated.
98#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
99pub enum DeprecatedSince {
100    RustcVersion(RustcVersion),
101    /// Deprecated in the future ("to be determined").
102    Future,
103    /// `feature(staged_api)` is off. Deprecation versions outside the standard
104    /// library are allowed to be arbitrary strings, for better or worse.
105    NonStandard(Symbol),
106    /// Deprecation version is unspecified but optional.
107    Unspecified,
108    /// Failed to parse a deprecation version, or the deprecation version is
109    /// unspecified and required. An error has already been emitted.
110    Err,
111}
112
113impl Deprecation {
114    /// Whether an item marked with #[deprecated(since = "X")] is currently
115    /// deprecated (i.e., whether X is not greater than the current rustc
116    /// version).
117    pub fn is_in_effect(&self) -> bool {
118        match self.since {
119            DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT,
120            DeprecatedSince::Future => false,
121            // The `since` field doesn't have semantic purpose without `#![staged_api]`.
122            DeprecatedSince::NonStandard(_) => true,
123            // Assume deprecation is in effect if "since" field is absent or invalid.
124            DeprecatedSince::Unspecified | DeprecatedSince::Err => true,
125        }
126    }
127
128    pub fn is_since_rustc_version(&self) -> bool {
129        matches!(self.since, DeprecatedSince::RustcVersion(_))
130    }
131}
132
133/// Represent parsed, *built in*, inert attributes.
134///
135/// That means attributes that are not actually ever expanded.
136/// For more information on this, see the module docs on the [`rustc_attr_parsing`] crate.
137/// They're instead used as markers, to guide the compilation process in various way in most every stage of the compiler.
138/// These are kept around after the AST, into the HIR and further on.
139///
140/// The word "parsed" could be a little misleading here, because the parser already parses
141/// attributes early on. However, the result, an [`ast::Attribute`]
142/// is only parsed at a high level, still containing a token stream in many cases. That is
143/// because the structure of the contents varies from attribute to attribute.
144/// With a parsed attribute I mean that each attribute is processed individually into a
145/// final structure, which on-site (the place where the attribute is useful for, think the
146/// the place where `must_use` is checked) little to no extra parsing or validating needs to
147/// happen.
148///
149/// For more docs, look in [`rustc_attr_parsing`].
150///
151/// [`rustc_attr_parsing`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html
152#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
153pub enum AttributeKind {
154    // tidy-alphabetical-start
155    /// Represents `#[rustc_allow_const_fn_unstable]`.
156    AllowConstFnUnstable(ThinVec<Symbol>),
157
158    /// Represents `#[allow_internal_unstable]`.
159    AllowInternalUnstable(ThinVec<(Symbol, Span)>),
160
161    /// Represents `#[rustc_default_body_unstable]`.
162    BodyStability {
163        stability: DefaultBodyStability,
164        /// Span of the `#[rustc_default_body_unstable(...)]` attribute
165        span: Span,
166    },
167
168    /// Represents `#[rustc_confusables]`.
169    Confusables {
170        symbols: ThinVec<Symbol>,
171        // FIXME(jdonszelmann): remove when target validation code is moved
172        first_span: Span,
173    },
174
175    /// Represents `#[rustc_const_stable]` and `#[rustc_const_unstable]`.
176    ConstStability {
177        stability: PartialConstStability,
178        /// Span of the `#[rustc_const_stable(...)]` or `#[rustc_const_unstable(...)]` attribute
179        span: Span,
180    },
181
182    /// Represents `#[rustc_const_stable_indirect]`.
183    ConstStabilityIndirect,
184
185    /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
186    Deprecation { deprecation: Deprecation, span: Span },
187
188    /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
189    DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },
190
191    /// Represents `#[rustc_macro_transparency]`.
192    MacroTransparency(Transparency),
193
194    /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
195    Repr(ThinVec<(ReprAttr, Span)>),
196
197    /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
198    Stability {
199        stability: Stability,
200        /// Span of the attribute.
201        span: Span,
202    },
203    // tidy-alphabetical-end
204}