2024-12-13 14:47:11 +01:00
|
|
|
use rustc_abi::Align;
|
2025-02-09 22:49:31 +01:00
|
|
|
use rustc_ast::token::CommentKind;
|
|
|
|
|
use rustc_ast::{self as ast, AttrStyle};
|
2025-02-09 22:50:03 +01:00
|
|
|
use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
|
2025-02-09 22:49:33 +01:00
|
|
|
use rustc_span::hygiene::Transparency;
|
2024-12-13 14:47:11 +01:00
|
|
|
use rustc_span::{Span, Symbol};
|
2025-02-09 22:49:33 +01:00
|
|
|
use thin_vec::ThinVec;
|
2024-12-13 14:47:11 +01:00
|
|
|
|
2025-02-09 22:50:03 +01:00
|
|
|
use crate::{DefaultBodyStability, PartialConstStability, PrintAttribute, RustcVersion, Stability};
|
2024-12-13 14:47:11 +01:00
|
|
|
|
2025-02-06 16:02:11 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic, PrintAttribute)]
|
2024-12-13 14:47:11 +01:00
|
|
|
pub enum InlineAttr {
|
|
|
|
|
None,
|
|
|
|
|
Hint,
|
|
|
|
|
Always,
|
|
|
|
|
Never,
|
2024-09-23 18:46:23 +01:00
|
|
|
/// `#[rustc_force_inline]` forces inlining to happen in the MIR inliner - it reports an error
|
|
|
|
|
/// if the inlining cannot happen. It is limited to only free functions so that the calls
|
|
|
|
|
/// can always be resolved.
|
|
|
|
|
Force {
|
|
|
|
|
attr_span: Span,
|
|
|
|
|
reason: Option<Symbol>,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl InlineAttr {
|
|
|
|
|
pub fn always(&self) -> bool {
|
|
|
|
|
match self {
|
|
|
|
|
InlineAttr::Always | InlineAttr::Force { .. } => true,
|
|
|
|
|
InlineAttr::None | InlineAttr::Hint | InlineAttr::Never => false,
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-13 14:47:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)]
|
|
|
|
|
pub enum InstructionSetAttr {
|
|
|
|
|
ArmA32,
|
|
|
|
|
ArmT32,
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-24 19:34:01 +00:00
|
|
|
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic, Default)]
|
2024-12-13 14:47:11 +01:00
|
|
|
pub enum OptimizeAttr {
|
2025-01-24 19:34:01 +00:00
|
|
|
/// No `#[optimize(..)]` attribute
|
|
|
|
|
#[default]
|
|
|
|
|
Default,
|
2024-12-09 19:00:43 +00:00
|
|
|
/// `#[optimize(none)]`
|
|
|
|
|
DoNotOptimize,
|
|
|
|
|
/// `#[optimize(speed)]`
|
2024-12-13 14:47:11 +01:00
|
|
|
Speed,
|
2024-12-09 19:00:43 +00:00
|
|
|
/// `#[optimize(size)]`
|
2024-12-13 14:47:11 +01:00
|
|
|
Size,
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-09 19:34:51 +00:00
|
|
|
impl OptimizeAttr {
|
|
|
|
|
pub fn do_not_optimize(&self) -> bool {
|
|
|
|
|
matches!(self, Self::DoNotOptimize)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-09 22:50:03 +01:00
|
|
|
#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, HashStable_Generic, PrintAttribute)]
|
2024-12-13 14:47:11 +01:00
|
|
|
pub enum ReprAttr {
|
|
|
|
|
ReprInt(IntType),
|
|
|
|
|
ReprRust,
|
|
|
|
|
ReprC,
|
|
|
|
|
ReprPacked(Align),
|
|
|
|
|
ReprSimd,
|
|
|
|
|
ReprTransparent,
|
|
|
|
|
ReprAlign(Align),
|
2025-02-09 22:49:33 +01:00
|
|
|
// this one is just so we can emit a lint for it
|
|
|
|
|
ReprEmpty,
|
2024-12-13 14:47:11 +01:00
|
|
|
}
|
|
|
|
|
pub use ReprAttr::*;
|
|
|
|
|
|
|
|
|
|
pub enum TransparencyError {
|
|
|
|
|
UnknownTransparency(Symbol, Span),
|
|
|
|
|
MultipleTransparencyAttrs(Span, Span),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
2025-02-09 22:50:03 +01:00
|
|
|
#[derive(Encodable, Decodable, HashStable_Generic, PrintAttribute)]
|
2024-12-13 14:47:11 +01:00
|
|
|
pub enum IntType {
|
|
|
|
|
SignedInt(ast::IntTy),
|
|
|
|
|
UnsignedInt(ast::UintTy),
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-09 22:50:03 +01:00
|
|
|
#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
|
2024-12-13 14:47:11 +01:00
|
|
|
pub struct Deprecation {
|
|
|
|
|
pub since: DeprecatedSince,
|
|
|
|
|
/// The note to issue a reason.
|
|
|
|
|
pub note: Option<Symbol>,
|
|
|
|
|
/// A text snippet used to completely replace any use of the deprecated item in an expression.
|
|
|
|
|
///
|
|
|
|
|
/// This is currently unstable.
|
|
|
|
|
pub suggestion: Option<Symbol>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Release in which an API is deprecated.
|
2025-02-09 22:50:03 +01:00
|
|
|
#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic, PrintAttribute)]
|
2024-12-13 14:47:11 +01:00
|
|
|
pub enum DeprecatedSince {
|
|
|
|
|
RustcVersion(RustcVersion),
|
|
|
|
|
/// Deprecated in the future ("to be determined").
|
|
|
|
|
Future,
|
|
|
|
|
/// `feature(staged_api)` is off. Deprecation versions outside the standard
|
|
|
|
|
/// library are allowed to be arbitrary strings, for better or worse.
|
|
|
|
|
NonStandard(Symbol),
|
|
|
|
|
/// Deprecation version is unspecified but optional.
|
|
|
|
|
Unspecified,
|
|
|
|
|
/// Failed to parse a deprecation version, or the deprecation version is
|
|
|
|
|
/// unspecified and required. An error has already been emitted.
|
|
|
|
|
Err,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Deprecation {
|
|
|
|
|
/// Whether an item marked with #[deprecated(since = "X")] is currently
|
|
|
|
|
/// deprecated (i.e., whether X is not greater than the current rustc
|
|
|
|
|
/// version).
|
|
|
|
|
pub fn is_in_effect(&self) -> bool {
|
|
|
|
|
match self.since {
|
|
|
|
|
DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT,
|
|
|
|
|
DeprecatedSince::Future => false,
|
|
|
|
|
// The `since` field doesn't have semantic purpose without `#![staged_api]`.
|
|
|
|
|
DeprecatedSince::NonStandard(_) => true,
|
|
|
|
|
// Assume deprecation is in effect if "since" field is absent or invalid.
|
|
|
|
|
DeprecatedSince::Unspecified | DeprecatedSince::Err => true,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn is_since_rustc_version(&self) -> bool {
|
|
|
|
|
matches!(self.since, DeprecatedSince::RustcVersion(_))
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-09 22:49:31 +01:00
|
|
|
|
2025-06-05 21:57:35 +08:00
|
|
|
/// Represents parsed *built-in* inert attributes.
|
2025-02-26 22:04:51 +00:00
|
|
|
///
|
2025-06-05 21:57:35 +08:00
|
|
|
/// ## Overview
|
|
|
|
|
/// These attributes are markers that guide the compilation process and are never expanded into other code.
|
|
|
|
|
/// They persist throughout the compilation phases, from AST to HIR and beyond.
|
2025-02-09 22:49:31 +01:00
|
|
|
///
|
2025-06-05 21:57:35 +08:00
|
|
|
/// ## Attribute Processing
|
|
|
|
|
/// While attributes are initially parsed by [`rustc_parse`] into [`ast::Attribute`], they still contain raw token streams
|
|
|
|
|
/// because different attributes have different internal structures. This enum represents the final,
|
|
|
|
|
/// fully parsed form of these attributes, where each variant contains contains all the information and
|
|
|
|
|
/// structure relevant for the specific attribute.
|
2025-02-09 22:49:31 +01:00
|
|
|
///
|
2025-06-05 21:57:35 +08:00
|
|
|
/// Some attributes can be applied multiple times to the same item, and they are "collapsed" into a single
|
|
|
|
|
/// semantic attribute. For example:
|
|
|
|
|
/// ```rust
|
|
|
|
|
/// #[repr(C)]
|
|
|
|
|
/// #[repr(packed)]
|
|
|
|
|
/// struct S { }
|
|
|
|
|
/// ```
|
|
|
|
|
/// This is equivalent to `#[repr(C, packed)]` and results in a single [`AttributeKind::Repr`] containing
|
|
|
|
|
/// both `C` and `packed` annotations. This collapsing happens during parsing and is reflected in the
|
|
|
|
|
/// data structures defined in this enum.
|
2025-02-26 22:04:51 +00:00
|
|
|
///
|
2025-06-05 21:57:35 +08:00
|
|
|
/// ## Usage
|
|
|
|
|
/// These parsed attributes are used throughout the compiler to:
|
|
|
|
|
/// - Control code generation (e.g., `#[repr]`)
|
|
|
|
|
/// - Mark API stability (`#[stable]`, `#[unstable]`)
|
|
|
|
|
/// - Provide documentation (`#[doc]`)
|
|
|
|
|
/// - Guide compiler behavior (e.g., `#[allow_internal_unstable]`)
|
|
|
|
|
///
|
|
|
|
|
/// ## Note on Attribute Organization
|
|
|
|
|
/// Some attributes like `InlineAttr`, `OptimizeAttr`, and `InstructionSetAttr` are defined separately
|
|
|
|
|
/// from this enum because they are used in specific compiler phases (like code generation) and don't
|
|
|
|
|
/// need to persist throughout the entire compilation process. They are typically processed and
|
|
|
|
|
/// converted into their final form earlier in the compilation pipeline.
|
|
|
|
|
///
|
|
|
|
|
/// For example:
|
|
|
|
|
/// - `InlineAttr` is used during code generation to control function inlining
|
|
|
|
|
/// - `OptimizeAttr` is used to control optimization levels
|
|
|
|
|
/// - `InstructionSetAttr` is used for target-specific code generation
|
|
|
|
|
///
|
|
|
|
|
/// These attributes are handled by their respective compiler passes in the [`rustc_codegen_ssa`] crate
|
|
|
|
|
/// and don't need to be preserved in the same way as the attributes in this enum.
|
|
|
|
|
///
|
|
|
|
|
/// For more details on attribute parsing, see the [`rustc_attr_parsing`] crate.
|
|
|
|
|
///
|
|
|
|
|
/// [`rustc_parse`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse/index.html
|
|
|
|
|
/// [`rustc_codegen_ssa`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/index.html
|
2025-02-26 22:04:51 +00:00
|
|
|
/// [`rustc_attr_parsing`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html
|
2025-02-09 22:50:03 +01:00
|
|
|
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
|
2025-02-09 22:49:31 +01:00
|
|
|
pub enum AttributeKind {
|
|
|
|
|
// tidy-alphabetical-start
|
2025-04-27 21:20:38 +02:00
|
|
|
/// Represents `#[rustc_allow_const_fn_unstable]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
AllowConstFnUnstable(ThinVec<Symbol>),
|
2025-04-27 21:20:38 +02:00
|
|
|
|
|
|
|
|
/// Represents `#[allow_internal_unstable]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
AllowInternalUnstable(ThinVec<(Symbol, Span)>),
|
2025-04-27 21:20:38 +02:00
|
|
|
|
2025-06-14 13:01:15 +03:00
|
|
|
/// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint).
|
|
|
|
|
AsPtr(Span),
|
|
|
|
|
|
2025-04-27 21:20:38 +02:00
|
|
|
/// Represents `#[rustc_default_body_unstable]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
BodyStability {
|
|
|
|
|
stability: DefaultBodyStability,
|
|
|
|
|
/// Span of the `#[rustc_default_body_unstable(...)]` attribute
|
|
|
|
|
span: Span,
|
|
|
|
|
},
|
2025-04-27 21:20:38 +02:00
|
|
|
|
|
|
|
|
/// Represents `#[rustc_confusables]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
Confusables {
|
|
|
|
|
symbols: ThinVec<Symbol>,
|
|
|
|
|
// FIXME(jdonszelmann): remove when target validation code is moved
|
|
|
|
|
first_span: Span,
|
|
|
|
|
},
|
2025-04-27 21:20:38 +02:00
|
|
|
|
|
|
|
|
/// Represents `#[rustc_const_stable]` and `#[rustc_const_unstable]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
ConstStability {
|
|
|
|
|
stability: PartialConstStability,
|
|
|
|
|
/// Span of the `#[rustc_const_stable(...)]` or `#[rustc_const_unstable(...)]` attribute
|
|
|
|
|
span: Span,
|
|
|
|
|
},
|
2025-04-27 21:20:38 +02:00
|
|
|
|
|
|
|
|
/// Represents `#[rustc_const_stable_indirect]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
ConstStabilityIndirect,
|
2025-04-27 21:20:38 +02:00
|
|
|
|
|
|
|
|
/// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute).
|
2025-06-10 08:48:56 +02:00
|
|
|
Deprecation { deprecation: Deprecation, span: Span },
|
2025-04-27 21:20:38 +02:00
|
|
|
|
|
|
|
|
/// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html).
|
2025-06-10 08:48:56 +02:00
|
|
|
DocComment { style: AttrStyle, kind: CommentKind, span: Span, comment: Symbol },
|
2025-04-27 21:20:38 +02:00
|
|
|
|
2025-06-10 08:48:56 +02:00
|
|
|
/// Represents `#[inline]` and `#[rustc_force_inline]`.
|
2025-02-06 16:02:11 +01:00
|
|
|
Inline(InlineAttr, Span),
|
2025-06-10 08:48:56 +02:00
|
|
|
|
|
|
|
|
/// Represents `#[rustc_macro_transparency]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
MacroTransparency(Transparency),
|
2025-04-27 21:20:38 +02:00
|
|
|
|
|
|
|
|
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
|
2025-02-09 22:49:33 +01:00
|
|
|
Repr(ThinVec<(ReprAttr, Span)>),
|
2025-06-10 08:48:56 +02:00
|
|
|
|
2025-04-27 21:20:38 +02:00
|
|
|
/// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`.
|
2025-02-09 22:49:33 +01:00
|
|
|
Stability {
|
|
|
|
|
stability: Stability,
|
2025-04-27 21:20:38 +02:00
|
|
|
/// Span of the attribute.
|
2025-02-09 22:49:33 +01:00
|
|
|
span: Span,
|
|
|
|
|
},
|
2025-02-09 22:49:31 +01:00
|
|
|
// tidy-alphabetical-end
|
|
|
|
|
}
|