| use std::borrow::Cow; | |
| use std::fmt; | |
| use std::path::PathBuf; | |
| pub use ReprAttr::*; | |
| use rustc_abi::Align; | |
| pub use rustc_ast::attr::data_structures::*; | |
| pub use rustc_ast::attr::version::RustcVersion; | |
| use rustc_ast::expand::autodiff_attrs::{DiffActivity, DiffMode}; | |
| use rustc_ast::expand::typetree::TypeTree; | |
| use rustc_ast::token::DocFragmentKind; | |
| use rustc_ast::{AttrStyle, Path, ast}; | |
| use rustc_data_structures::Limit; | |
| use rustc_data_structures::fx::FxIndexMap; | |
| use rustc_error_messages::{DiagArgValue, IntoDiagArg}; | |
| use rustc_macros::{Decodable, Encodable, PrintAttribute, StableHash}; | |
| use rustc_span::def_id::DefId; | |
| use rustc_span::hygiene::Transparency; | |
| use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol}; | |
| pub use rustc_target::spec::SanitizerSet; | |
| use thin_vec::ThinVec; | |
| pub use crate::attrs::canonical_symbols::{CanonicalSymbol, CanonicalSymbols}; | |
| use crate::attrs::diagnostic::*; | |
| use crate::attrs::pretty_printing::PrintAttribute; | |
| use crate::{DefaultBodyStability, LangItem, PartialConstStability, Stability}; | |
| #[derive(Copy, Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub enum EiiImplResolution { | |
| /// Usually, finding the extern item that an EII implementation implements means finding | |
| /// the defid of the associated attribute macro, and looking at *its* attributes to find | |
| /// what foreign item its associated with. | |
| Macro(DefId), | |
| /// Sometimes though, we already know statically and can skip some name resolution. | |
| /// DefId of the extern item that the EII implementation implements. | |
| Known(DefId), | |
| /// For when resolution failed, but we want to continue compilation | |
| Error(ErrorGuaranteed), | |
| } | |
| #[derive(Copy, Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub struct EiiImpl { | |
| pub resolution: EiiImplResolution, | |
| pub impl_unsafe_span: Option<Span>, | |
| pub span: Span, | |
| pub inner_span: Span, | |
| pub is_default: bool, | |
| } | |
| #[derive(Copy, Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub struct EiiDecl { | |
| pub foreign_item: DefId, | |
| /// whether or not it is unsafe to implement this EII | |
| pub impl_unsafe: bool, | |
| pub name: Ident, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, StableHash, PrintAttribute)] | |
| pub enum CguKind { | |
| No, | |
| PreDashLto, | |
| PostDashLto, | |
| Any, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, StableHash, PrintAttribute)] | |
| pub enum CguFields { | |
| PartitionReused { cfg: Symbol, module: Symbol }, | |
| PartitionCodegened { cfg: Symbol, module: Symbol }, | |
| ExpectedCguReuse { cfg: Symbol, module: Symbol, kind: CguKind }, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Debug, PrintAttribute)] | |
| #[derive(StableHash, Encodable, Decodable)] | |
| pub enum DivergingFallbackBehavior { | |
| /// Always fallback to `()` (aka "always spontaneous decay") | |
| ToUnit, | |
| /// Always fallback to `!` (which should be equivalent to never falling back + not making | |
| /// never-to-any coercions unless necessary) | |
| ToNever, | |
| /// Don't fallback at all | |
| NoFallback, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Debug, PrintAttribute, Default)] | |
| #[derive(StableHash, Encodable, Decodable)] | |
| pub enum DivergingBlockBehavior { | |
| /// This is the current stable behavior: | |
| /// | |
| /// ```rust | |
| /// { | |
| /// return; | |
| /// } // block has type = !, even though we are supposedly dropping it with `;` | |
| /// ``` | |
| #[default] | |
| Never, | |
| /// Alternative behavior: | |
| /// | |
| /// ```ignore (very-unstable-new-attribute) | |
| /// #![rustc_never_type_options(diverging_block_default = "unit")] | |
| /// { | |
| /// return; | |
| /// } // block has type = (), since we are dropping `!` from `return` with `;` | |
| /// ``` | |
| Unit, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, StableHash, PrintAttribute)] | |
| pub enum InlineAttr { | |
| None, | |
| Hint, | |
| Always, | |
| Never, | |
| /// `#[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, | |
| } | |
| } | |
| } | |
| #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, StableHash, PrintAttribute)] | |
| pub enum UnrollAttr { | |
| Hint, | |
| Full, | |
| Never, | |
| Count(u32), | |
| } | |
| #[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq, StableHash, PrintAttribute)] | |
| pub enum InstructionSetAttr { | |
| ArmA32, | |
| ArmT32, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, Eq, StableHash, PrintAttribute)] | |
| pub enum InstrumentFnAttr { | |
| /// `#[instrument_fn = "on"]` | |
| On, | |
| /// `#[instrument_fn = "off"]` | |
| Off, | |
| } | |
| #[derive(Copy, Clone, Debug, PartialEq, Eq, Default, PrintAttribute)] | |
| #[derive(Encodable, Decodable, StableHash)] | |
| pub enum OptimizeAttr { | |
| /// No `#[optimize(..)]` attribute | |
| #[default] | |
| Default, | |
| /// `#[optimize(none)]` | |
| DoNotOptimize, | |
| /// `#[optimize(speed)]` | |
| Speed, | |
| /// `#[optimize(size)]` | |
| Size, | |
| } | |
| impl OptimizeAttr { | |
| pub fn do_not_optimize(&self) -> bool { | |
| matches!(self, Self::DoNotOptimize) | |
| } | |
| } | |
| #[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, StableHash, PrintAttribute)] | |
| pub enum ReprAttr { | |
| ReprInt(IntType), | |
| ReprRust, | |
| ReprC, | |
| ReprPacked(Align), | |
| ReprSimd, | |
| ReprTransparent, | |
| ReprAlign(Align), | |
| } | |
| pub enum TransparencyError { | |
| UnknownTransparency(Symbol, Span), | |
| MultipleTransparencyAttrs(Span, Span), | |
| } | |
| #[derive(Eq, PartialEq, Debug, Copy, Clone)] | |
| #[derive(Encodable, Decodable, StableHash, PrintAttribute)] | |
| pub enum IntType { | |
| SignedInt(ast::IntTy), | |
| UnsignedInt(ast::UintTy), | |
| } | |
| #[derive(Copy, Debug, Encodable, Decodable, Clone, StableHash, PrintAttribute)] | |
| pub struct Deprecation { | |
| pub since: DeprecatedSince, | |
| /// The note to issue a reason. | |
| pub note: Option<Ident>, | |
| /// 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. | |
| #[derive(Copy, Debug, Encodable, Decodable, Clone, StableHash, PrintAttribute)] | |
| 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, | |
| } | |
| /// Successfully-parsed value of a `#[coverage(..)]` attribute. | |
| #[derive(Copy, Debug, Eq, PartialEq, Encodable, Decodable, Clone)] | |
| #[derive(StableHash, PrintAttribute)] | |
| pub enum CoverageAttrKind { | |
| On, | |
| Off, | |
| } | |
| /// Successfully-parsed value of a `#[rustc_abi(..)]` attribute. | |
| #[derive(Copy, Debug, Eq, PartialEq, Encodable, Decodable, Clone)] | |
| #[derive(StableHash, PrintAttribute)] | |
| pub enum RustcAbiAttrKind { | |
| Debug, | |
| AssertEq, | |
| } | |
| 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(_)) | |
| } | |
| } | |
| /// There are three valid forms of the attribute: | |
| /// `#[used]`, which is equivalent to `#[used(linker)]` on targets that support it, but `#[used(compiler)]` if not. | |
| /// `#[used(compiler)]` | |
| /// `#[used(linker)]` | |
| #[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)] | |
| #[derive(StableHash, PrintAttribute)] | |
| pub enum UsedBy { | |
| Default, | |
| Compiler, | |
| Linker, | |
| } | |
| #[derive(Encodable, Decodable, Clone, Debug, PartialEq, Eq, Hash)] | |
| #[derive(StableHash, PrintAttribute)] | |
| pub enum MacroUseArgs { | |
| UseAll, | |
| UseSpecific(ThinVec<Ident>), | |
| } | |
| impl Default for MacroUseArgs { | |
| fn default() -> Self { | |
| Self::UseSpecific(ThinVec::new()) | |
| } | |
| } | |
| #[derive(Debug, Clone, Encodable, Decodable, StableHash)] | |
| pub struct StrippedCfgItem<ScopeId = DefId> { | |
| pub parent_scope: ScopeId, | |
| pub ident: Ident, | |
| pub cfg: (CfgEntry, Span), | |
| } | |
| impl<ScopeId> StrippedCfgItem<ScopeId> { | |
| pub fn map_scope_id<New>(self, f: impl FnOnce(ScopeId) -> New) -> StrippedCfgItem<New> { | |
| StrippedCfgItem { parent_scope: f(self.parent_scope), ident: self.ident, cfg: self.cfg } | |
| } | |
| } | |
| /// Possible values for the `#[linkage]` attribute, allowing to specify the | |
| /// linkage type for a `MonoItem`. | |
| /// | |
| /// See <https://llvm.org/docs/LangRef.html#linkage-types> for more details about these variants. | |
| #[derive(Encodable, Decodable, Clone, Copy, Debug, PartialEq, Eq, Hash)] | |
| #[derive(StableHash, PrintAttribute)] | |
| pub enum Linkage { | |
| AvailableExternally, | |
| Common, | |
| ExternalWeak, | |
| External, | |
| Internal, | |
| LinkOnceAny, | |
| LinkOnceODR, | |
| WeakAny, | |
| WeakODR, | |
| } | |
| #[derive(Clone, Copy, Decodable, Debug, Encodable, PartialEq)] | |
| #[derive(StableHash, PrintAttribute)] | |
| pub enum MirDialect { | |
| Analysis, | |
| Built, | |
| Runtime, | |
| } | |
| impl IntoDiagArg for MirDialect { | |
| fn into_diag_arg(self, _path: &mut Option<PathBuf>) -> DiagArgValue { | |
| let arg = match self { | |
| MirDialect::Analysis => "analysis", | |
| MirDialect::Built => "built", | |
| MirDialect::Runtime => "runtime", | |
| }; | |
| DiagArgValue::Str(Cow::Borrowed(arg)) | |
| } | |
| } | |
| #[derive(Clone, Copy, Decodable, Debug, Encodable, PartialEq)] | |
| #[derive(StableHash, PrintAttribute)] | |
| pub enum MirPhase { | |
| Initial, | |
| PostCleanup, | |
| Optimized, | |
| } | |
| impl IntoDiagArg for MirPhase { | |
| fn into_diag_arg(self, _path: &mut Option<PathBuf>) -> DiagArgValue { | |
| let arg = match self { | |
| MirPhase::Initial => "initial", | |
| MirPhase::PostCleanup => "post-cleanup", | |
| MirPhase::Optimized => "optimized", | |
| }; | |
| DiagArgValue::Str(Cow::Borrowed(arg)) | |
| } | |
| } | |
| /// Different ways that the PE Format can decorate a symbol name. | |
| /// From <https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type> | |
| #[derive(Copy, Clone, Debug, Encodable, Decodable, StableHash, PartialEq, Eq, PrintAttribute)] | |
| pub enum PeImportNameType { | |
| /// IMPORT_ORDINAL | |
| /// Uses the ordinal (i.e., a number) rather than the name. | |
| Ordinal(u16), | |
| /// Same as IMPORT_NAME | |
| /// Name is decorated with all prefixes and suffixes. | |
| Decorated, | |
| /// Same as IMPORT_NAME_NOPREFIX | |
| /// Prefix (e.g., the leading `_` or `@`) is skipped, but suffix is kept. | |
| NoPrefix, | |
| /// Same as IMPORT_NAME_UNDECORATE | |
| /// Prefix (e.g., the leading `_` or `@`) and suffix (the first `@` and all | |
| /// trailing characters) are skipped. | |
| Undecorated, | |
| } | |
| #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] | |
| #[derive(Encodable, Decodable, PrintAttribute)] | |
| #[derive(StableHash)] | |
| pub enum NativeLibKind { | |
| /// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC) | |
| Static { | |
| /// Whether to bundle objects from static library into produced rlib | |
| bundle: Option<bool>, | |
| /// Whether to link static library without throwing any object files away | |
| whole_archive: Option<bool>, | |
| /// Whether to export c static library symbols | |
| export_symbols: Option<bool>, | |
| }, | |
| /// Dynamic library (e.g. `libfoo.so` on Linux) | |
| /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). | |
| Dylib { | |
| /// Whether the dynamic library will be linked only if it satisfies some undefined symbols | |
| as_needed: Option<bool>, | |
| }, | |
| /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library. | |
| /// On Linux, it refers to a generated shared library stub. | |
| RawDylib { | |
| /// Whether the dynamic library will be linked only if it satisfies some undefined symbols | |
| as_needed: Option<bool>, | |
| }, | |
| /// A macOS-specific kind of dynamic libraries. | |
| Framework { | |
| /// Whether the framework will be linked only if it satisfies some undefined symbols | |
| as_needed: Option<bool>, | |
| }, | |
| /// Argument which is passed to linker, relative order with libraries and other arguments | |
| /// is preserved | |
| LinkArg, | |
| /// Module imported from WebAssembly | |
| WasmImportModule, | |
| /// The library kind wasn't specified, `Dylib` is currently used as a default. | |
| Unspecified, | |
| } | |
| impl NativeLibKind { | |
| pub fn has_modifiers(&self) -> bool { | |
| match self { | |
| NativeLibKind::Static { bundle, whole_archive, export_symbols } => { | |
| bundle.is_some() || whole_archive.is_some() || export_symbols.is_some() | |
| } | |
| NativeLibKind::Dylib { as_needed } | |
| | NativeLibKind::Framework { as_needed } | |
| | NativeLibKind::RawDylib { as_needed } => as_needed.is_some(), | |
| NativeLibKind::Unspecified | |
| | NativeLibKind::LinkArg | |
| | NativeLibKind::WasmImportModule => false, | |
| } | |
| } | |
| pub fn is_statically_included(&self) -> bool { | |
| matches!(self, NativeLibKind::Static { .. }) | |
| } | |
| pub fn is_dllimport(&self) -> bool { | |
| matches!( | |
| self, | |
| NativeLibKind::Dylib { .. } | |
| | NativeLibKind::RawDylib { .. } | |
| | NativeLibKind::Unspecified | |
| ) | |
| } | |
| } | |
| #[derive(Debug, Encodable, Decodable, Clone, StableHash, PrintAttribute)] | |
| pub struct LinkEntry { | |
| pub span: Span, | |
| pub kind: NativeLibKind, | |
| pub name: Symbol, | |
| pub cfg: Option<CfgEntry>, | |
| pub verbatim: Option<bool>, | |
| pub import_name_type: Option<(PeImportNameType, Span)>, | |
| } | |
| #[derive(StableHash, PrintAttribute)] | |
| #[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)] | |
| pub enum DebuggerVisualizerType { | |
| Natvis, | |
| GdbPrettyPrinter, | |
| } | |
| #[derive(Debug, Encodable, Decodable, Clone, StableHash, PrintAttribute)] | |
| pub struct DebugVisualizer { | |
| pub span: Span, | |
| pub visualizer_type: DebuggerVisualizerType, | |
| pub path: Symbol, | |
| } | |
| #[derive(Clone, Copy, Debug, Decodable, Encodable, Eq, PartialEq)] | |
| #[derive(StableHash, PrintAttribute)] | |
| #[derive_const(Default)] | |
| pub enum RtsanSetting { | |
| Nonblocking, | |
| Blocking, | |
| #[default] | |
| Caller, | |
| } | |
| #[derive(Eq, PartialEq, Debug, Copy, Clone)] | |
| #[derive(Encodable, Decodable, StableHash, PrintAttribute)] | |
| pub enum WindowsSubsystemKind { | |
| Console, | |
| Windows, | |
| } | |
| impl WindowsSubsystemKind { | |
| pub fn as_str(&self) -> &'static str { | |
| match self { | |
| WindowsSubsystemKind::Console => "console", | |
| WindowsSubsystemKind::Windows => "windows", | |
| } | |
| } | |
| } | |
| #[derive(Copy, Clone, Debug, PartialEq)] | |
| #[derive(StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub enum DocInline { | |
| Inline, | |
| NoInline, | |
| } | |
| #[derive(Copy, Clone, Debug, PartialEq)] | |
| #[derive(StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub enum HideOrShow { | |
| Hide, | |
| Show, | |
| } | |
| #[derive(Clone, Copy, Debug, StableHash, Encodable, Decodable, PrintAttribute, PartialEq)] | |
| pub struct DocCfgHideShowValue { | |
| pub span: Span, | |
| /// If `value` is `None`, then it's a `none()` value. | |
| pub value: Option<Symbol>, | |
| } | |
| impl DocCfgHideShowValue { | |
| pub fn new(value: Symbol, span: Span) -> Self { | |
| Self { span, value: Some(value) } | |
| } | |
| pub fn new_none(span: Span) -> Self { | |
| Self { span, value: None } | |
| } | |
| } | |
| #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute, PartialEq)] | |
| pub enum DocCfgHideShow { | |
| Any(Span), | |
| List(ThinVec<DocCfgHideShowValue>), | |
| } | |
| impl DocCfgHideShow { | |
| pub fn new() -> Self { | |
| Self::List(ThinVec::new()) | |
| } | |
| pub fn new_with_only_key(span: Span) -> Self { | |
| let mut values = ThinVec::with_capacity(1); | |
| values.push(DocCfgHideShowValue { span, value: None }); | |
| Self::List(values) | |
| } | |
| pub fn push_none(&mut self, span: Span) { | |
| if let Self::List(values) = self | |
| && !values.iter().any(|v| v.value.is_none()) | |
| { | |
| values.push(DocCfgHideShowValue { span, value: None }); | |
| } | |
| } | |
| pub fn merge_with(&mut self, other: &Self) { | |
| match (self, other) { | |
| (Self::Any(_), Self::Any(_) | Self::List(_)) => { | |
| // Nothing to do. | |
| } | |
| (s, Self::Any(span)) => { | |
| // We "upgrade" the list values to "all". | |
| *s = Self::Any(*span); | |
| } | |
| (Self::List(values), Self::List(other_values)) => { | |
| // Having duplicates is not an issue, we simply ignore them. Would be more | |
| // convenient to have a `set` type though. T_T | |
| for other in other_values { | |
| if !values.iter().any(|value| value.value == other.value) { | |
| values.push(*other); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub struct CfgHideShow { | |
| pub kind: HideOrShow, | |
| pub values: FxIndexMap<Symbol, DocCfgHideShow>, | |
| } | |
| #[derive(Clone, Debug, Default, StableHash, Decodable, PrintAttribute)] | |
| pub struct DocAttribute { | |
| pub first_span: Span, | |
| pub aliases: FxIndexMap<Symbol, Span>, | |
| pub hidden: Option<Span>, | |
| // Because we need to emit the error if there is more than one `inline` attribute on an item | |
| // at the same time as the other doc attributes, we store a list instead of using `Option`. | |
| pub inline: ThinVec<(DocInline, Span)>, | |
| // unstable | |
| pub cfg: ThinVec<CfgEntry>, | |
| pub auto_cfg: ThinVec<(CfgHideShow, Span)>, | |
| /// This is for `#[doc(auto_cfg = false|true)]`/`#[doc(auto_cfg)]`. | |
| pub auto_cfg_change: ThinVec<(bool, Span)>, | |
| // builtin | |
| pub fake_variadic: Option<Span>, | |
| pub keyword: Option<(Symbol, Span)>, | |
| pub attribute: Option<(Symbol, Span)>, | |
| pub masked: Option<Span>, | |
| pub notable_trait: Option<Span>, | |
| pub search_unbox: Option<Span>, | |
| // valid on crate | |
| pub html_favicon_url: Option<(Symbol, Span)>, | |
| pub html_logo_url: Option<(Symbol, Span)>, | |
| pub html_playground_url: Option<(Symbol, Span)>, | |
| pub html_root_url: Option<(Symbol, Span)>, | |
| pub html_no_source: Option<Span>, | |
| pub issue_tracker_base_url: Option<(Symbol, Span)>, | |
| pub rust_logo: Option<Span>, | |
| // #[doc(test(...))] | |
| pub test_attrs: ThinVec<Span>, | |
| pub no_crate_inject: Option<Span>, | |
| } | |
| impl<E: rustc_span::SpanEncoder> rustc_serialize::Encodable<E> for DocAttribute { | |
| fn encode(&self, encoder: &mut E) { | |
| let DocAttribute { | |
| first_span, | |
| aliases, | |
| hidden, | |
| inline, | |
| cfg, | |
| auto_cfg, | |
| auto_cfg_change, | |
| fake_variadic, | |
| keyword, | |
| attribute, | |
| masked, | |
| notable_trait, | |
| search_unbox, | |
| html_favicon_url, | |
| html_logo_url, | |
| html_playground_url, | |
| html_root_url, | |
| html_no_source, | |
| issue_tracker_base_url, | |
| rust_logo, | |
| test_attrs, | |
| no_crate_inject, | |
| } = self; | |
| rustc_serialize::Encodable::<E>::encode(first_span, encoder); | |
| rustc_serialize::Encodable::<E>::encode(aliases, encoder); | |
| rustc_serialize::Encodable::<E>::encode(hidden, encoder); | |
| // FIXME: The `doc(inline)` attribute is never encoded, but is it actually the right thing | |
| // to do? I suspect the condition was broken, should maybe instead not encode anything if we | |
| // have `doc(no_inline)`. | |
| let inline: ThinVec<_> = | |
| inline.iter().filter(|(i, _)| *i != DocInline::Inline).cloned().collect(); | |
| rustc_serialize::Encodable::<E>::encode(&inline, encoder); | |
| rustc_serialize::Encodable::<E>::encode(cfg, encoder); | |
| rustc_serialize::Encodable::<E>::encode(auto_cfg, encoder); | |
| rustc_serialize::Encodable::<E>::encode(auto_cfg_change, encoder); | |
| rustc_serialize::Encodable::<E>::encode(fake_variadic, encoder); | |
| rustc_serialize::Encodable::<E>::encode(keyword, encoder); | |
| rustc_serialize::Encodable::<E>::encode(attribute, encoder); | |
| rustc_serialize::Encodable::<E>::encode(masked, encoder); | |
| rustc_serialize::Encodable::<E>::encode(notable_trait, encoder); | |
| rustc_serialize::Encodable::<E>::encode(search_unbox, encoder); | |
| rustc_serialize::Encodable::<E>::encode(html_favicon_url, encoder); | |
| rustc_serialize::Encodable::<E>::encode(html_logo_url, encoder); | |
| rustc_serialize::Encodable::<E>::encode(html_playground_url, encoder); | |
| rustc_serialize::Encodable::<E>::encode(html_root_url, encoder); | |
| rustc_serialize::Encodable::<E>::encode(html_no_source, encoder); | |
| rustc_serialize::Encodable::<E>::encode(issue_tracker_base_url, encoder); | |
| rustc_serialize::Encodable::<E>::encode(rust_logo, encoder); | |
| rustc_serialize::Encodable::<E>::encode(test_attrs, encoder); | |
| rustc_serialize::Encodable::<E>::encode(no_crate_inject, encoder); | |
| } | |
| } | |
| /// How to perform collapse macros debug info | |
| /// if-ext - if macro from different crate (related to callsite code) | |
| /// | cmd \ attr | no | (unspecified) | external | yes | | |
| /// | no | no | no | no | no | | |
| /// | (unspecified) | no | no | if-ext | yes | | |
| /// | external | no | if-ext | if-ext | yes | | |
| /// | yes | yes | yes | yes | yes | | |
| #[derive(Copy, Clone, Debug, Hash, PartialEq)] | |
| #[derive(StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub enum CollapseMacroDebuginfo { | |
| /// Don't collapse debuginfo for the macro | |
| No = 0, | |
| /// Unspecified value | |
| Unspecified = 1, | |
| /// Collapse debuginfo if the macro comes from a different crate | |
| External = 2, | |
| /// Collapse debuginfo for the macro | |
| Yes = 3, | |
| } | |
| /// Crate type, as specified by `#![crate_type]` | |
| #[derive(Copy, Clone, Debug, Hash, PartialEq, Default, PartialOrd, Eq, Ord)] | |
| #[derive(StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub enum CrateType { | |
| /// `#![crate_type = "bin"]` | |
| Executable, | |
| /// `#![crate_type = "dylib"]` | |
| Dylib, | |
| /// `#![crate_type = "rlib"]` or `#![crate_type = "lib"]` | |
| #[default] | |
| Rlib, | |
| /// `#![crate_type = "staticlib"]` | |
| StaticLib, | |
| /// `#![crate_type = "cdylib"]` | |
| Cdylib, | |
| /// `#![crate_type = "proc-macro"]` | |
| ProcMacro, | |
| /// `#![crate_type = "sdylib"]` | |
| // Unstable; feature(export_stable) | |
| Sdylib, | |
| } | |
| impl CrateType { | |
| /// Pairs of each `#[crate_type] = "..."` value and the crate type it resolves to | |
| pub fn all() -> &'static [(Symbol, Self)] { | |
| debug_assert_eq!(CrateType::default(), CrateType::Rlib); | |
| &[ | |
| (rustc_span::sym::lib, CrateType::Rlib), | |
| (rustc_span::sym::rlib, CrateType::Rlib), | |
| (rustc_span::sym::dylib, CrateType::Dylib), | |
| (rustc_span::sym::cdylib, CrateType::Cdylib), | |
| (rustc_span::sym::staticlib, CrateType::StaticLib), | |
| (rustc_span::sym::proc_dash_macro, CrateType::ProcMacro), | |
| (rustc_span::sym::bin, CrateType::Executable), | |
| (rustc_span::sym::sdylib, CrateType::Sdylib), | |
| ] | |
| } | |
| /// Same as [`CrateType::all`], but does not include unstable options. | |
| /// Used for diagnostics. | |
| pub fn all_stable() -> &'static [(Symbol, Self)] { | |
| debug_assert_eq!(CrateType::default(), CrateType::Rlib); | |
| &[ | |
| (rustc_span::sym::lib, CrateType::Rlib), | |
| (rustc_span::sym::rlib, CrateType::Rlib), | |
| (rustc_span::sym::dylib, CrateType::Dylib), | |
| (rustc_span::sym::cdylib, CrateType::Cdylib), | |
| (rustc_span::sym::staticlib, CrateType::StaticLib), | |
| (rustc_span::sym::proc_dash_macro, CrateType::ProcMacro), | |
| (rustc_span::sym::bin, CrateType::Executable), | |
| ] | |
| } | |
| pub fn has_metadata(self) -> bool { | |
| match self { | |
| CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true, | |
| CrateType::Executable | |
| | CrateType::Cdylib | |
| | CrateType::StaticLib | |
| | CrateType::Sdylib => false, | |
| } | |
| } | |
| } | |
| impl TryFrom<Symbol> for CrateType { | |
| type Error = (); | |
| fn try_from(value: Symbol) -> Result<Self, Self::Error> { | |
| Ok(match value { | |
| rustc_span::sym::bin => CrateType::Executable, | |
| rustc_span::sym::dylib => CrateType::Dylib, | |
| rustc_span::sym::staticlib => CrateType::StaticLib, | |
| rustc_span::sym::cdylib => CrateType::Cdylib, | |
| rustc_span::sym::rlib => CrateType::Rlib, | |
| rustc_span::sym::lib => CrateType::default(), | |
| rustc_span::sym::proc_dash_macro => CrateType::ProcMacro, | |
| rustc_span::sym::sdylib => CrateType::Sdylib, | |
| _ => return Err(()), | |
| }) | |
| } | |
| } | |
| impl std::fmt::Display for CrateType { | |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
| match *self { | |
| CrateType::Executable => "bin".fmt(f), | |
| CrateType::Dylib => "dylib".fmt(f), | |
| CrateType::Rlib => "rlib".fmt(f), | |
| CrateType::StaticLib => "staticlib".fmt(f), | |
| CrateType::Cdylib => "cdylib".fmt(f), | |
| CrateType::ProcMacro => "proc-macro".fmt(f), | |
| CrateType::Sdylib => "sdylib".fmt(f), | |
| } | |
| } | |
| } | |
| impl IntoDiagArg for CrateType { | |
| fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue { | |
| self.to_string().into_diag_arg(&mut None) | |
| } | |
| } | |
| #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub enum RustcDumpLayoutKind { | |
| Align, | |
| BackendRepr, | |
| Debug, | |
| HomogenousAggregate, | |
| LargestNiche, | |
| Size, | |
| } | |
| #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute, PartialEq, Eq)] | |
| pub enum RustcMirKind { | |
| PeekMaybeInit, | |
| PeekMaybeUninit, | |
| PeekLiveness, | |
| StopAfterDataflow, | |
| BorrowckGraphvizPostflow { path: PathBuf }, | |
| BorrowckGraphvizFormat { format: BorrowckGraphvizFormatKind }, | |
| } | |
| #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute, PartialEq, Eq)] | |
| pub enum BorrowckGraphvizFormatKind { | |
| TwoPhase, | |
| } | |
| #[derive(Clone, Debug, PartialEq, Eq)] | |
| #[derive(StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub struct RustcCleanAttribute { | |
| pub span: Span, | |
| pub cfg: Symbol, | |
| pub except: Option<RustcCleanQueries>, | |
| pub loaded_from_disk: Option<RustcCleanQueries>, | |
| } | |
| /// Represents the `except=` or `loaded_from_disk=` argument of `#[rustc_clean]` | |
| #[derive(Clone, Debug, PartialEq, Eq)] | |
| #[derive(StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub struct RustcCleanQueries { | |
| pub entries: ThinVec<Symbol>, | |
| pub span: Span, | |
| } | |
| #[derive(Clone, Debug, PartialEq, Eq)] | |
| #[derive(StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub struct RustcAutodiff { | |
| /// Conceptually either forward or reverse mode AD, as described in various autodiff papers and | |
| /// e.g. in the [JAX | |
| /// Documentation](https://jax.readthedocs.io/en/latest/_tutorials/advanced-autodiff.html#how-it-s-made-two-foundational-autodiff-functions). | |
| pub mode: DiffMode, | |
| /// A user-provided, batching width. If not given, we will default to 1 (no batching). | |
| /// Calling a differentiated, non-batched function through a loop 100 times is equivalent to: | |
| /// - Calling the function 50 times with a batch size of 2 | |
| /// - Calling the function 25 times with a batch size of 4, | |
| /// etc. A batched function takes more (or longer) arguments, and might be able to benefit from | |
| /// cache locality, better re-usal of primal values, and other optimizations. | |
| /// We will (before LLVM's vectorizer runs) just generate most LLVM-IR instructions `width` | |
| /// times, so this massively increases code size. As such, values like 1024 are unlikely to | |
| /// work. We should consider limiting this to u8 or u16, but will leave it at u32 for | |
| /// experiments for now and focus on documenting the implications of a large width. | |
| pub width: u32, | |
| pub input_activity: ThinVec<DiffActivity>, | |
| pub ret_activity: DiffActivity, | |
| } | |
| impl RustcAutodiff { | |
| pub fn has_primal_ret(&self) -> bool { | |
| matches!(self.ret_activity, DiffActivity::Active | DiffActivity::Dual) | |
| } | |
| } | |
| impl RustcAutodiff { | |
| pub fn has_ret_activity(&self) -> bool { | |
| self.ret_activity != DiffActivity::None | |
| } | |
| pub fn has_active_only_ret(&self) -> bool { | |
| self.ret_activity == DiffActivity::ActiveOnly | |
| } | |
| pub fn error() -> Self { | |
| RustcAutodiff { | |
| mode: DiffMode::Error, | |
| width: 0, | |
| ret_activity: DiffActivity::None, | |
| input_activity: ThinVec::new(), | |
| } | |
| } | |
| pub fn source() -> Self { | |
| RustcAutodiff { | |
| mode: DiffMode::Source, | |
| width: 0, | |
| ret_activity: DiffActivity::None, | |
| input_activity: ThinVec::new(), | |
| } | |
| } | |
| pub fn is_active(&self) -> bool { | |
| self.mode != DiffMode::Error | |
| } | |
| pub fn is_source(&self) -> bool { | |
| self.mode == DiffMode::Source | |
| } | |
| pub fn apply_autodiff(&self) -> bool { | |
| !matches!(self.mode, DiffMode::Error | DiffMode::Source) | |
| } | |
| pub fn into_item( | |
| self, | |
| source: String, | |
| target: String, | |
| inputs: Vec<TypeTree>, | |
| output: TypeTree, | |
| ) -> AutoDiffItem { | |
| AutoDiffItem { source, target, inputs, output, attrs: self } | |
| } | |
| } | |
| /// We generate one of these structs for each `#[autodiff(...)]` attribute. | |
| #[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, StableHash)] | |
| pub struct AutoDiffItem { | |
| /// The name of the function getting differentiated | |
| pub source: String, | |
| /// The name of the function being generated | |
| pub target: String, | |
| pub attrs: RustcAutodiff, | |
| pub inputs: Vec<TypeTree>, | |
| pub output: TypeTree, | |
| } | |
| impl fmt::Display for AutoDiffItem { | |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| write!(f, "Differentiating {} -> {}", self.source, self.target)?; | |
| write!(f, " with attributes: {:?}", self.attrs)?; | |
| write!(f, " with inputs: {:?}", self.inputs)?; | |
| write!(f, " with output: {:?}", self.output) | |
| } | |
| } | |
| #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub struct UnstableRemovedFeature { | |
| pub feature: Symbol, | |
| pub reason: Symbol, | |
| pub link: Symbol, | |
| pub since: RustcVersion, | |
| } | |
| /// Represents parsed *built-in* inert attributes. | |
| /// | |
| /// ## 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. | |
| /// | |
| /// ## 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 all the information and | |
| /// structure relevant for the specific attribute. | |
| /// | |
| /// 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. | |
| /// | |
| /// ## 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 | |
| /// [`rustc_attr_parsing`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html | |
| #[derive(Clone, Debug, StableHash, Encodable, Decodable, PrintAttribute)] | |
| pub enum AttributeKind { | |
| // tidy-alphabetical-start | |
| /// Represents `#[allow_internal_unsafe]`. | |
| AllowInternalUnsafe(Span), | |
| /// Represents `#[allow_internal_unstable]`. | |
| AllowInternalUnstable(ThinVec<(Symbol, Span)>, Span), | |
| /// Represents `#[automatically_derived]` | |
| AutomaticallyDerived, | |
| /// Represents the trace attribute of `#[cfg_attr]` | |
| CfgAttrTrace(ThinVec<(CfgEntry, Span)>), | |
| /// Represents the trace attribute of `#[cfg]` | |
| CfgTrace(ThinVec<(CfgEntry, Span)>), | |
| /// Represents `#[cfi_encoding]` | |
| CfiEncoding { | |
| encoding: Symbol, | |
| }, | |
| /// Represents `#[cold]`. | |
| Cold, | |
| /// Represents `#[collapse_debuginfo]`. | |
| CollapseDebugInfo(CollapseMacroDebuginfo), | |
| /// Represents `#[compiler_builtins]`. | |
| CompilerBuiltins, | |
| /// Represents `#[const_continue]`. | |
| ConstContinue(Span), | |
| /// Represents `#[coroutine]`. | |
| Coroutine, | |
| /// Represents `#[coverage(..)]`. | |
| Coverage(CoverageAttrKind), | |
| /// Represents `#[crate_name = ...]` | |
| CrateName { | |
| name: Symbol, | |
| name_span: Span, | |
| attr_span: Span, | |
| }, | |
| /// Represents `#![crate_type = ...]` | |
| CrateType(ThinVec<CrateType>), | |
| /// Represents `#[custom_mir]`. | |
| CustomMir(Option<(MirDialect, Span)>, Option<(MirPhase, Span)>), | |
| /// Represents `#[debugger_visualizer]`. | |
| DebuggerVisualizer(ThinVec<DebugVisualizer>), | |
| /// Represents `#![default_lib_allocator]` | |
| DefaultLibAllocator, | |
| /// Represents [`#[deprecated]`](https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html#the-deprecated-attribute). | |
| Deprecated { | |
| deprecation: Deprecation, | |
| span: Span, | |
| }, | |
| /// Represents `#[diagnostic::do_not_recommend]`. | |
| DoNotRecommend, | |
| /// Represents [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). | |
| /// Represents all other uses of the [`#[doc]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html) | |
| /// attribute. | |
| Doc(Box<DocAttribute>), | |
| /// Represents specifically [`#[doc = "..."]`](https://doc.rust-lang.org/stable/rustdoc/write-documentation/the-doc-attribute.html). | |
| /// i.e. doc comments. | |
| DocComment { | |
| style: AttrStyle, | |
| kind: DocFragmentKind, | |
| span: Span, | |
| comment: Symbol, | |
| }, | |
| /// Implementation detail of `#[eii]` | |
| EiiDeclaration(EiiDecl), | |
| /// Implementation detail of `#[eii]` | |
| EiiImpl(Box<EiiImpl>), | |
| /// Represents [`#[export_name]`](https://doc.rust-lang.org/reference/abi.html#the-export_name-attribute). | |
| ExportName { | |
| /// The name to export this item with. | |
| /// It may not contain \0 bytes as it will be converted to a null-terminated string. | |
| name: Symbol, | |
| span: Span, | |
| }, | |
| /// Represents `#[export_stable]`. | |
| ExportStable, | |
| /// Represents `#[feature(...)]` | |
| Feature(ThinVec<Ident>, Span), | |
| /// Represents `#[ffi_const]`. | |
| FfiConst, | |
| /// Represents `#[ffi_pure]`. | |
| FfiPure(Span), | |
| /// Represents `#[fundamental]`. | |
| Fundamental, | |
| /// Represents `#[ignore]` | |
| Ignore { | |
| span: Span, | |
| /// ignore can optionally have a reason: `#[ignore = "reason this is ignored"]` | |
| reason: Option<Symbol>, | |
| }, | |
| /// Represents `#[inline]` and `#[rustc_force_inline]`. | |
| Inline(InlineAttr, Span), | |
| /// Represents `#[instruction_set]` | |
| InstructionSet(InstructionSetAttr), | |
| /// Represents `#[instrument_fn]` | |
| InstrumentFn(InstrumentFnAttr), | |
| /// Represents `#[lang]` | |
| Lang(LangItem), | |
| /// Represents `#[link]`. | |
| Link(ThinVec<LinkEntry>, Span), | |
| /// Represents `#[link_name]`. | |
| LinkName { | |
| name: Symbol, | |
| span: Span, | |
| }, | |
| /// Represents `#[link_ordinal]`. | |
| LinkOrdinal { | |
| ordinal: u16, | |
| span: Span, | |
| }, | |
| /// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute) | |
| LinkSection { | |
| name: Symbol, | |
| }, | |
| /// Represents `#[linkage]`. | |
| Linkage(Linkage, Span), | |
| /// Represents `#[loop_match]`. | |
| LoopMatch(Span), | |
| /// Represents `#[macro_escape]`. | |
| MacroEscape, | |
| /// Represents [`#[macro_export]`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path). | |
| MacroExport { | |
| span: Span, | |
| local_inner_macros: bool, | |
| }, | |
| /// Represents `#[macro_use]`. | |
| MacroUse { | |
| span: Span, | |
| arguments: MacroUseArgs, | |
| }, | |
| /// Represents `#[marker]`. | |
| Marker, | |
| /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). | |
| MayDangle(Span), | |
| /// Represents `#[move_size_limit]` | |
| MoveSizeLimit { | |
| limit: Limit, | |
| }, | |
| /// Represents `#[must_not_suspend]` | |
| MustNotSupend { | |
| reason: Option<Symbol>, | |
| }, | |
| /// Represents `#[must_use]`. | |
| MustUse { | |
| /// Used by `clippy`. | |
| span: Span, | |
| /// must_use can optionally have a reason: `#[must_use = "reason this must be used"]` | |
| reason: Option<Symbol>, | |
| }, | |
| /// Represents `#[naked]` | |
| Naked(Span), | |
| /// Represents `#[needs_allocator]` | |
| NeedsAllocator, | |
| /// Represents `#[needs_panic_runtime]` | |
| NeedsPanicRuntime, | |
| /// Represents `#[no_builtins]` | |
| NoBuiltins, | |
| /// Represents `#[no_core]` | |
| NoCore, | |
| /// Represents `#[no_implicit_prelude]` | |
| NoImplicitPrelude, | |
| /// Represents `#[no_link]` | |
| NoLink, | |
| /// Represents `#[no_main]` | |
| NoMain, | |
| /// Represents `#[no_mangle]` | |
| NoMangle(Span), | |
| /// Represents `#[no_std]` | |
| NoStd, | |
| /// Represents `#[non_exhaustive]` | |
| NonExhaustive(Span), | |
| /// Represents `#[diagnostic::on_const]`. | |
| OnConst { | |
| /// The attribute path span. | |
| span: Span, | |
| /// None if the directive was malformed in some way. | |
| directive: Option<Box<Directive>>, | |
| }, | |
| /// Represents `#[diagnostic::on_move]` | |
| OnMove { | |
| directive: Option<Box<Directive>>, | |
| }, | |
| /// Represents`#[diagnostic::on_type_error]`. | |
| OnTypeError { | |
| span: Span, | |
| directive: Option<Box<Directive>>, | |
| }, | |
| /// Represents `#[rustc_on_unimplemented]` and `#[diagnostic::on_unimplemented]`. | |
| OnUnimplemented { | |
| /// None if the directive was malformed in some way. | |
| directive: Option<Box<Directive>>, | |
| }, | |
| /// Represents `#[diagnostic::on_unknown]` | |
| OnUnknown { | |
| /// None if the directive was malformed in some way. | |
| directive: Option<Box<Directive>>, | |
| }, | |
| /// Represents `#[diagnostic::on_unmatched_args]`. | |
| OnUnmatchedArgs { | |
| /// None if the directive was malformed in some way. | |
| directive: Option<Box<Directive>>, | |
| }, | |
| /// Represents `#[diagnostic::opaque]`. | |
| Opaque, | |
| /// Represents `#[optimize(size|speed)]` | |
| Optimize(OptimizeAttr, Span), | |
| /// Represents `#[panic_runtime]` | |
| PanicRuntime, | |
| /// Represents `#[patchable_function_entry]` | |
| PatchableFunctionEntry { | |
| prefix: Option<u8>, | |
| entry: Option<u8>, | |
| section: Option<Symbol>, | |
| }, | |
| /// Represents `#[path]` | |
| Path(Symbol), | |
| /// Represents `#[pattern_complexity_limit]` | |
| PatternComplexityLimit { | |
| limit: Limit, | |
| }, | |
| /// Represents `#[pin_v2]` | |
| PinV2(Span), | |
| /// Represents `#[prelude_import]` | |
| PreludeImport, | |
| /// Represents `#[proc_macro]` | |
| ProcMacro, | |
| /// Represents `#[proc_macro_attribute]` | |
| ProcMacroAttribute, | |
| /// Represents `#[proc_macro_derive]` | |
| ProcMacroDerive { | |
| trait_name: Symbol, | |
| helper_attrs: ThinVec<Symbol>, | |
| }, | |
| /// Represents `#[profiler_runtime]` | |
| ProfilerRuntime, | |
| /// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute) | |
| RecursionLimit { | |
| limit: Limit, | |
| }, | |
| /// Represents `#[reexport_test_harness_main]` | |
| ReexportTestHarnessMain(Symbol), | |
| /// Represents `#[register_attribute_tool]`, `#[register_lint_tool]` and `#[register_tool]` | |
| RegisterTool { | |
| attr_tools: ThinVec<Ident>, | |
| lint_tools: ThinVec<Ident>, | |
| }, | |
| /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). | |
| Repr { | |
| reprs: ThinVec<(ReprAttr, Span)>, | |
| first_span: Span, | |
| }, | |
| /// Represents `#[rustc_abi(..)]` | |
| RustcAbi { | |
| attr_span: Span, | |
| kind: RustcAbiAttrKind, | |
| }, | |
| /// Represents `#[align(N)]`. | |
| // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity | |
| RustcAlign { | |
| align: Align, | |
| span: Span, | |
| }, | |
| /// Represents `#[rustc_allocator]` | |
| RustcAllocator, | |
| /// Represents `#[rustc_allocator_zeroed]` | |
| RustcAllocatorZeroed, | |
| /// Represents `#[rustc_allocator_zeroed_variant]` | |
| RustcAllocatorZeroedVariant { | |
| name: Symbol, | |
| }, | |
| /// Represents `#[rustc_allow_const_fn_unstable]`. | |
| RustcAllowConstFnUnstable(ThinVec<Symbol>, Span), | |
| /// Represents `#[rustc_allow_incoherent_impl]`. | |
| RustcAllowIncoherentImpl(Span), | |
| /// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint). | |
| RustcAsPtr, | |
| /// Represents `#[rustc_autodiff]`. | |
| RustcAutodiff(Option<Box<RustcAutodiff>>), | |
| /// Represents `#[rustc_default_body_unstable]`. | |
| RustcBodyStability { | |
| stability: DefaultBodyStability, | |
| /// Span of the `#[rustc_default_body_unstable(...)]` attribute | |
| span: Span, | |
| }, | |
| /// Represents `#[rustc_builtin_macro]`. | |
| RustcBuiltinMacro { | |
| builtin_name: Option<Symbol>, | |
| helper_attrs: ThinVec<Symbol>, | |
| }, | |
| /// Represents `#[rustc_canonical_symbol]` | |
| RustcCanonicalSymbol, | |
| /// Represents `#[rustc_capture_analysis]` | |
| RustcCaptureAnalysis, | |
| /// Represents `#[rustc_expected_cgu_reuse]`, `#[rustc_partition_codegened]` and `#[rustc_partition_reused]`. | |
| RustcCguTestAttr(ThinVec<(Span, CguFields)>), | |
| /// Represents `#[rustc_clean]` | |
| RustcClean(ThinVec<RustcCleanAttribute>), | |
| /// Represents `#[rustc_coherence_is_core]` | |
| RustcCoherenceIsCore, | |
| /// Represents `#[rustc_coinductive]`. | |
| RustcCoinductive, | |
| /// Represents `#[rustc_comptime]` | |
| RustcComptime(Span), | |
| /// Represents `#[rustc_confusables]`. | |
| RustcConfusables { | |
| confusables: ThinVec<Symbol>, | |
| }, | |
| /// Represents `#[rustc_const_stable]` and `#[rustc_const_unstable]`. | |
| RustcConstStability { | |
| stability: PartialConstStability, | |
| /// Path span of the `#[rustc_const_stable(...)]` or `#[rustc_const_unstable(...)]` | |
| /// attribute. | |
| span: Span, | |
| }, | |
| /// Represents `#[rustc_const_stable_indirect]`. | |
| RustcConstStableIndirect, | |
| /// Represents `#[rustc_conversion_suggestion]` | |
| RustcConversionSuggestion, | |
| /// Represents `#[rustc_deallocator]` | |
| RustcDeallocator, | |
| /// Represents `#[rustc_delayed_bug_from_inside_query]` | |
| RustcDelayedBugFromInsideQuery, | |
| /// Represents `#[rustc_deny_explicit_impl]`. | |
| RustcDenyExplicitImpl, | |
| /// Represents `#[rustc_deprecated_safe_2024]` | |
| RustcDeprecatedSafe2024 { | |
| suggestion: Symbol, | |
| }, | |
| /// Represents `#[rustc_diagnostic_item]` | |
| RustcDiagnosticItem(Symbol), | |
| /// Represents `#[rustc_do_not_const_check]` | |
| RustcDoNotConstCheck, | |
| /// Represents `#[rustc_doc_primitive = ...]` | |
| RustcDocPrimitive(Span, Symbol), | |
| /// Represents `#[rustc_dummy]`. | |
| RustcDummy, | |
| /// Represents `#[rustc_dump_def_parents]` | |
| RustcDumpDefParents, | |
| /// Represents `#[rustc_dump_def_path]` | |
| RustcDumpDefPath(Span), | |
| /// Represents `#[rustc_dump_generics]` | |
| RustcDumpGenerics, | |
| /// Represents `#[rustc_dump_hidden_type_of_opaques]` | |
| RustcDumpHiddenTypeOfOpaques, | |
| /// Represents `#[rustc_dump_inferred_outlives]` | |
| RustcDumpInferredOutlives, | |
| /// Represents `#[rustc_dump_item_bounds]` | |
| RustcDumpItemBounds, | |
| /// Represents `#[rustc_dump_layout]` | |
| RustcDumpLayout(ThinVec<RustcDumpLayoutKind>), | |
| /// Represents `#[rustc_dump_object_lifetime_defaults]`. | |
| RustcDumpObjectLifetimeDefaults, | |
| /// Represents `#[rustc_dump_predicates]` | |
| RustcDumpPredicates, | |
| /// Represents `#[rustc_dump_symbol_name]` | |
| RustcDumpSymbolName(Span), | |
| /// Represents `#[rustc_dump_user_args]` | |
| RustcDumpUserArgs, | |
| /// Represents `#[rustc_dump_variances]` | |
| RustcDumpVariances, | |
| /// Represents `#[rustc_dump_variances_of_opaques]` | |
| RustcDumpVariancesOfOpaques, | |
| /// Represents `#[rustc_dump_vtable]` | |
| RustcDumpVtable(Span), | |
| /// Represents `#[rustc_dyn_incompatible_trait]`. | |
| RustcDynIncompatibleTrait(Span), | |
| /// Represents `#[rustc_effective_visibility]`. | |
| RustcEffectiveVisibility, | |
| /// Implementation detail of `#[eii]` | |
| RustcEiiForeignItem, | |
| /// Represents `#[rustc_evaluate_where_clauses]` | |
| RustcEvaluateWhereClauses, | |
| RustcHasIncoherentInherentImpls, | |
| /// Represents `#[rustc_if_this_changed]` | |
| RustcIfThisChanged(Span, Option<Symbol>), | |
| /// Represents `#[rustc_inherit_overflow_checks]` | |
| RustcInheritOverflowChecks, | |
| /// Represents `#[rustc_insignificant_dtor]` | |
| RustcInsignificantDtor, | |
| /// Represents `#[rustc_intrinsic]` | |
| RustcIntrinsic, | |
| /// Represents `#[rustc_intrinsic_const_stable_indirect]` | |
| RustcIntrinsicConstStableIndirect, | |
| /// Represents `#[rustc_legacy_const_generics]` | |
| RustcLegacyConstGenerics { | |
| fn_indexes: ThinVec<(usize, Span)>, | |
| attr_span: Span, | |
| }, | |
| /// Represents `#[rustc_lint_opt_deny_field_access]` | |
| RustcLintOptDenyFieldAccess { | |
| lint_message: Symbol, | |
| }, | |
| /// Represents `#[rustc_lint_opt_ty]` | |
| RustcLintOptTy, | |
| /// Represents `#[rustc_lint_query_instability]` | |
| RustcLintQueryInstability, | |
| /// Represents `#[rustc_lint_untracked_query_information]` | |
| RustcLintUntrackedQueryInformation, | |
| /// Represents `#[rustc_macro_transparency]`. | |
| RustcMacroTransparency(Transparency), | |
| /// Represents `#[rustc_main]`. | |
| RustcMain, | |
| /// Represents `#[rustc_mir]`. | |
| RustcMir(ThinVec<RustcMirKind>), | |
| /// Represents `#[rustc_must_implement_one_of]` | |
| RustcMustImplementOneOf { | |
| attr_span: Span, | |
| fn_names: ThinVec<Ident>, | |
| }, | |
| /// Represents `#[rustc_must_match_exhaustively]` | |
| RustcMustMatchExhaustively(Span), | |
| /// Represents `#[rustc_never_returns_null_ptr]` | |
| RustcNeverReturnsNullPtr, | |
| /// Represents `#[rustc_never_type_options]`. | |
| RustcNeverTypeOptions { | |
| fallback: Option<DivergingFallbackBehavior>, | |
| diverging_block_default: Option<DivergingBlockBehavior>, | |
| }, | |
| /// Represents `#[rustc_no_implicit_autorefs]` | |
| RustcNoImplicitAutorefs, | |
| /// Represents `#[rustc_no_implicit_bounds]` | |
| RustcNoImplicitBounds, | |
| /// Represents `#[rustc_no_mir_inline]` | |
| RustcNoMirInline, | |
| /// Represents `#[rustc_no_writable]` | |
| RustcNoWritable, | |
| /// Represents `#[rustc_non_const_trait_method]`. | |
| RustcNonConstTraitMethod, | |
| /// Represents `#[rustc_nonnull_optimization_guaranteed]`. | |
| RustcNonnullOptimizationGuaranteed, | |
| /// Represents `#[rustc_nounwind]` | |
| RustcNounwind, | |
| /// Represents `#[rustc_objc_class]` | |
| RustcObjcClass { | |
| classname: Symbol, | |
| }, | |
| /// Represents `#[rustc_objc_selector]` | |
| RustcObjcSelector { | |
| methname: Symbol, | |
| }, | |
| /// Represents `#[rustc_offload_kernel]` | |
| RustcOffloadKernel, | |
| /// Represents `#[rustc_panics_when_zero]` (used for linting). | |
| RustcPanicsWhenZero, | |
| /// Represents `#[rustc_paren_sugar]`. | |
| RustcParenSugar, | |
| /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint). | |
| RustcPassByValue, | |
| /// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]` | |
| RustcPassIndirectlyInNonRusticAbis(Span), | |
| /// Represents `#[rustc_preserve_ub_checks]` | |
| RustcPreserveUbChecks, | |
| /// Represents `#[rustc_proc_macro_decls]` | |
| RustcProcMacroDecls, | |
| /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint). | |
| RustcPubTransparent(Span), | |
| /// Represents `#[rustc_reallocator]` | |
| RustcReallocator, | |
| /// Represents `#[rustc_regions]` | |
| RustcRegions, | |
| /// Represents `#[rustc_reservation_impl]` | |
| RustcReservationImpl(Symbol), | |
| /// Represents `#[rustc_scalable_vector(N)]` | |
| RustcScalableVector { | |
| /// The base multiple of lanes that are in a scalable vector, if provided. `element_count` | |
| /// is not provided for representing tuple types. | |
| element_count: Option<u16>, | |
| }, | |
| /// Represents `#[rustc_should_not_be_called_on_const_items]` | |
| RustcShouldNotBeCalledOnConstItems, | |
| /// Represents `#[rustc_simd_monomorphize_lane_limit = "N"]`. | |
| RustcSimdMonomorphizeLaneLimit(Limit), | |
| /// Represents `#[rustc_skip_during_method_dispatch]`. | |
| RustcSkipDuringMethodDispatch { | |
| array: bool, | |
| boxed_slice: bool, | |
| }, | |
| /// Represents `#[rustc_specialization_trait]`. | |
| RustcSpecializationTrait, | |
| /// Represents `#[rustc_std_internal_symbol]`. | |
| RustcStdInternalSymbol, | |
| /// Represents `#[rustc_strict_coherence]`. | |
| RustcStrictCoherence(Span), | |
| /// Represents `#[rustc_test_entrypoint_marker]` | |
| RustcTestEntrypointMarker, | |
| /// Represents `#[rustc_test_marker]` | |
| RustcTestMarker(Symbol), | |
| /// Represents `#[rustc_then_this_would_need]` | |
| RustcThenThisWouldNeed(ThinVec<Ident>), | |
| /// Represents `#[rustc_trivial_field_reads]` | |
| RustcTrivialFieldReads, | |
| /// Represents `#[rustc_unsafe_specialization_marker]`. | |
| RustcUnsafeSpecializationMarker, | |
| /// Represents `#[sanitize]` | |
| /// | |
| /// the on set and off set are distjoint since there's a third option: unset. | |
| /// a node may not set the sanitizer setting in which case it inherits from parents. | |
| /// rtsan is unset if None | |
| Sanitize { | |
| on_set: SanitizerSet, | |
| off_set: SanitizerSet, | |
| rtsan: Option<RtsanSetting>, | |
| span: Span, | |
| }, | |
| /// Represents `#[should_panic]` | |
| ShouldPanic { | |
| reason: Option<Symbol>, | |
| }, | |
| /// Represents `#[rustc_splat]` | |
| Splat(Span), | |
| /// Represents `#[stable]`, `#[unstable]` and `#[rustc_allowed_through_unstable_modules]`. | |
| Stability { | |
| stability: Stability, | |
| /// Span of the attribute. | |
| span: Span, | |
| }, | |
| /// Represents `#[target_feature(enable = "...")]` and | |
| /// `#[unsafe(force_target_feature(enable = "...")]`. | |
| TargetFeature { | |
| features: ThinVec<(Symbol, Span)>, | |
| attr_span: Span, | |
| was_forced: bool, | |
| }, | |
| /// Represents `#![test_runner(path)]` | |
| TestRunner(Path), | |
| /// Represents `#[thread_local]` | |
| ThreadLocal, | |
| /// Represents `#[track_caller]` | |
| TrackCaller(Span), | |
| /// Represents `#[type_length_limit]` | |
| TypeLengthLimit { | |
| limit: Limit, | |
| }, | |
| /// Represents `#[unroll]` | |
| Unroll(UnrollAttr), | |
| /// Represents `#[unstable_feature_bound]`. | |
| UnstableFeatureBound(ThinVec<(Symbol, Span)>), | |
| /// Represents all `#![unstable_removed(...)]` features | |
| UnstableRemoved(ThinVec<UnstableRemovedFeature>), | |
| /// Represents `#[used]` | |
| Used { | |
| used_by: UsedBy, | |
| }, | |
| /// Represents `#[windows_subsystem]`. | |
| WindowsSubsystem(WindowsSubsystemKind), | |
| // tidy-alphabetical-end | |
| } |