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}