about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs58
-rw-r--r--compiler/rustc_attr_data_structures/src/lib.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs5
-rw-r--r--compiler/rustc_expand/src/base.rs3
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs64
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs27
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs33
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs8
-rw-r--r--compiler/rustc_smir/src/stable_mir/compiler_interface.rs23
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs15
11 files changed, 194 insertions, 48 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index 845e4d5e5d0..a0a50fd4b7c 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -130,24 +130,54 @@ impl Deprecation {
     }
 }
 
-/// Represent parsed, *built in*, inert attributes.
+/// Represents parsed *built-in* inert attributes.
 ///
-/// That means attributes that are not actually ever expanded.
-/// For more information on this, see the module docs on the [`rustc_attr_parsing`] crate.
-/// They're instead used as markers, to guide the compilation process in various way in most every stage of the compiler.
-/// These are kept around after the AST, into the HIR and further on.
+/// ## 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.
 ///
-/// The word "parsed" could be a little misleading here, because the parser already parses
-/// attributes early on. However, the result, an [`ast::Attribute`]
-/// is only parsed at a high level, still containing a token stream in many cases. That is
-/// because the structure of the contents varies from attribute to attribute.
-/// With a parsed attribute I mean that each attribute is processed individually into a
-/// final structure, which on-site (the place where the attribute is useful for, think the
-/// the place where `must_use` is checked) little to no extra parsing or validating needs to
-/// happen.
+/// ## 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.
 ///
-/// For more docs, look in [`rustc_attr_parsing`].
+/// 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, HashStable_Generic, Encodable, Decodable, PrintAttribute)]
 pub enum AttributeKind {
diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs
index b0fc19d1cd7..f8355be09ad 100644
--- a/compiler/rustc_attr_data_structures/src/lib.rs
+++ b/compiler/rustc_attr_data_structures/src/lib.rs
@@ -1,3 +1,7 @@
+//! Data structures for representing parsed attributes in the Rust compiler.
+//! For detailed documentation about attribute processing,
+//! see [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html).
+
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![doc(rust_logo)]
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index b439fa34f5b..b067578794b 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -118,10 +118,7 @@ pub(crate) fn expand_test_or_bench(
 
     let (item, is_stmt) = match item {
         Annotatable::Item(i) => (i, false),
-        Annotatable::Stmt(stmt) if matches!(stmt.kind, ast::StmtKind::Item(_)) => {
-            // FIXME: Use an 'if let' guard once they are implemented
-            if let ast::StmtKind::Item(i) = stmt.kind { (i, true) } else { unreachable!() }
-        }
+        Annotatable::Stmt(box ast::Stmt { kind: ast::StmtKind::Item(i), .. }) => (i, true),
         other => {
             not_testable_error(cx, attr_sp, None);
             return vec![other];
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 311dadb53c4..7a29f8c9fbd 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -35,6 +35,7 @@ use crate::base::ast::MetaItemInner;
 use crate::errors;
 use crate::expand::{self, AstFragment, Invocation};
 use crate::module::DirOwnership;
+use crate::stats::MacroStat;
 
 // When adding new variants, make sure to
 // adjust the `visit_*` / `flat_map_*` calls in `InvocationCollector`
@@ -1191,7 +1192,7 @@ pub struct ExtCtxt<'a> {
     /// not to expand it again.
     pub(super) expanded_inert_attrs: MarkedAttrs,
     /// `-Zmacro-stats` data.
-    pub macro_stats: FxHashMap<(Symbol, MacroKind), crate::stats::MacroStat>, // njn: quals
+    pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
 }
 
 impl<'a> ExtCtxt<'a> {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 73a21789c5d..7d6e471e7e9 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -887,7 +887,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_legacy_const_generics, Normal, template!(List: "N"), ErrorFollowing,
         EncodeCrossCrate::Yes,
     ),
-    // Do not const-check this function's body. It will always get replaced during CTFE.
+    // Do not const-check this function's body. It will always get replaced during CTFE via `hook_special_const_fn`.
     rustc_attr!(
         rustc_do_not_const_check, Normal, template!(Word), WarnFollowing,
         EncodeCrossCrate::Yes, "`#[rustc_do_not_const_check]` skips const-check for this function's body",
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 15e8c1ef3cc..63312eff490 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1,8 +1,64 @@
-//! Defines the various compiler queries.
 //!
-//! For more information on the query system, see
-//! ["Queries: demand-driven compilation"](https://rustc-dev-guide.rust-lang.org/query.html).
-//! This chapter includes instructions for adding new queries.
+//! # The rustc Query System: Query Definitions and Modifiers
+//!
+//! The core processes in rustc are shipped as queries. Each query is a demand-driven function from some key to a value.
+//! The execution result of the function is cached and directly read during the next request, thereby improving compilation efficiency.
+//! Some results are saved locally and directly read during the next compilation, which are core of incremental compilation.
+//!
+//! ## How to Read This Module
+//!
+//! Each `query` block in this file defines a single query, specifying its key and value types, along with various modifiers.
+//! These query definitions are processed by the [`rustc_macros`], which expands them into the necessary boilerplate code
+//! for the query system—including the [`Providers`] struct (a function table for all query implementations, where each field is
+//! a function pointer to the actual provider), caching, and dependency graph integration.
+//! **Note:** The `Providers` struct is not a Rust trait, but a struct generated by the `rustc_macros` to hold all provider functions.
+//! The `rustc_macros` also supports a set of **query modifiers** (see below) that control the behavior of each query.
+//!
+//! The actual provider functions are implemented in various modules and registered into the `Providers` struct
+//! during compiler initialization (see [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]).
+//!
+//! [`rustc_macros`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_macros/index.html
+//! [`rustc_interface::passes::DEFAULT_QUERY_PROVIDERS`]: ../../rustc_interface/passes/static.DEFAULT_QUERY_PROVIDERS.html
+//!
+//! ## Query Modifiers
+//!
+//! Query modifiers are special flags that alter the behavior of a query. They are parsed and processed by the `rustc_macros`
+//! The main modifiers are:
+//!
+//! - `desc { ... }`: Sets the human-readable description for diagnostics and profiling. Required for every query.
+//! - `arena_cache`: Use an arena for in-memory caching of the query result.
+//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to true.
+//! - `fatal_cycle`: If a dependency cycle is detected, abort compilation with a fatal error.
+//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately.
+//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling.
+//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed.
+//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created).
+//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results.
+//! - `depth_limit`: Impose a recursion depth limit on the query to prevent stack overflows.
+//! - `separate_provide_extern`: Use separate provider functions for local and external crates.
+//! - `feedable`: Allow the query result to be set from another query ("fed" externally).
+//! - `return_result_from_ensure_ok`: When called via `tcx.ensure_ok()`, return `Result<(), ErrorGuaranteed>` instead of `()`.
+//!   If the query needs to be executed and returns an error, the error is returned to the caller.
+//!   Only valid for queries returning `Result<_, ErrorGuaranteed>`.
+//!
+//! For the up-to-date list, see the `QueryModifiers` struct in
+//! [`rustc_macros/src/query.rs`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/query.rs)
+//! and for more details in incremental compilation, see the
+//! [Query modifiers in incremental compilation](https://rustc-dev-guide.rust-lang.org/queries/incremental-compilation-in-detail.html#query-modifiers) section of the rustc-dev-guide.
+//!
+//! ## Query Expansion and Code Generation
+//!
+//! The [`rustc_macros::rustc_queries`] macro expands each query definition into:
+//! - A method on [`TyCtxt`] (and [`TyCtxtAt`]) for invoking the query.
+//! - Provider traits and structs for supplying the query's value.
+//! - Caching and dependency graph integration.
+//! - Support for incremental compilation, disk caching, and arena allocation as controlled by the modifiers.
+//!
+//! [`rustc_macros::rustc_queries`]: ../../rustc_macros/macro.rustc_queries.html
+//!
+//! The macro-based approach allows the query system to be highly flexible and maintainable, while minimizing boilerplate.
+//!
+//! For more details, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/query.html).
 
 #![allow(unused_parens)]
 
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index b49a13ce584..215202c4bd5 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2273,23 +2273,18 @@ impl<'a> Parser<'a> {
                     ),
                     // Also catches `fn foo(&a)`.
                     PatKind::Ref(ref inner_pat, mutab)
-                        if matches!(inner_pat.clone().kind, PatKind::Ident(..)) =>
+                        if let PatKind::Ident(_, ident, _) = inner_pat.clone().kind =>
                     {
-                        match inner_pat.clone().kind {
-                            PatKind::Ident(_, ident, _) => {
-                                let mutab = mutab.prefix_str();
-                                (
-                                    ident,
-                                    "self: ",
-                                    format!("{ident}: &{mutab}TypeName"),
-                                    "_: ",
-                                    pat.span.shrink_to_lo(),
-                                    pat.span,
-                                    pat.span.shrink_to_lo(),
-                                )
-                            }
-                            _ => unreachable!(),
-                        }
+                        let mutab = mutab.prefix_str();
+                        (
+                            ident,
+                            "self: ",
+                            format!("{ident}: &{mutab}TypeName"),
+                            "_: ",
+                            pat.span.shrink_to_lo(),
+                            pat.span,
+                            pat.span.shrink_to_lo(),
+                        )
                     }
                     _ => {
                         // Otherwise, try to get a type and emit a suggestion.
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index ef8c88355f6..baa4c0681e8 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -12,7 +12,8 @@ use rustc_middle::ty::layout::{
 };
 use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
 use rustc_middle::ty::{
-    GenericPredicates, Instance, List, ScalarInt, TyCtxt, TypeVisitableExt, ValTree,
+    CoroutineArgsExt, GenericPredicates, Instance, List, ScalarInt, TyCtxt, TypeVisitableExt,
+    ValTree,
 };
 use rustc_middle::{mir, ty};
 use rustc_span::def_id::LOCAL_CRATE;
@@ -22,9 +23,9 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef};
 use stable_mir::mir::{BinOp, Body, Place, UnOp};
 use stable_mir::target::{MachineInfo, MachineSize};
 use stable_mir::ty::{
-    AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
-    ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, Ty,
-    TyConst, TyKind, UintTy, VariantDef,
+    AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef,
+    ForeignDef, ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy,
+    Span, Ty, TyConst, TyKind, UintTy, VariantDef, VariantIdx,
 };
 use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol};
 
@@ -447,6 +448,30 @@ impl<'tcx> SmirCtxt<'tcx> {
         def.internal(&mut *tables, tcx).variants().len()
     }
 
+    /// Discriminant for a given variant index of AdtDef
+    pub fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr {
+        let mut tables = self.0.borrow_mut();
+        let tcx = tables.tcx;
+        let adt = adt.internal(&mut *tables, tcx);
+        let variant = variant.internal(&mut *tables, tcx);
+        adt.discriminant_for_variant(tcx, variant).stable(&mut *tables)
+    }
+
+    /// Discriminant for a given variand index and args of a coroutine
+    pub fn coroutine_discr_for_variant(
+        &self,
+        coroutine: CoroutineDef,
+        args: &GenericArgs,
+        variant: VariantIdx,
+    ) -> Discr {
+        let mut tables = self.0.borrow_mut();
+        let tcx = tables.tcx;
+        let coroutine = coroutine.def_id().internal(&mut *tables, tcx);
+        let args = args.internal(&mut *tables, tcx);
+        let variant = variant.internal(&mut *tables, tcx);
+        args.as_coroutine().discriminant_for_variant(coroutine, tcx, variant).stable(&mut *tables)
+    }
+
     /// The name of a variant.
     pub fn variant_name(&self, def: VariantDef) -> Symbol {
         let mut tables = self.0.borrow_mut();
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index 6a26f5f7997..b4239ddd896 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -960,3 +960,11 @@ impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData {
         }
     }
 }
+
+impl<'tcx> Stable<'tcx> for rustc_middle::ty::util::Discr<'tcx> {
+    type T = stable_mir::ty::Discr;
+
+    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
+        stable_mir::ty::Discr { val: self.val, ty: self.ty.stable(tables) }
+    }
+}
diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs
index 3967ad13eeb..2668fba9f4f 100644
--- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs
+++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs
@@ -13,10 +13,10 @@ use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef};
 use stable_mir::mir::{BinOp, Body, Place, UnOp};
 use stable_mir::target::MachineInfo;
 use stable_mir::ty::{
-    AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
-    ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
-    ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl,
-    TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
+    AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef,
+    ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates,
+    Generics, ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span,
+    TraitDecl, TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, VariantIdx,
 };
 use stable_mir::{
     AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls,
@@ -230,6 +230,21 @@ impl<'tcx> SmirInterface<'tcx> {
         self.cx.adt_variants_len(def)
     }
 
+    /// Discriminant for a given variant index of AdtDef
+    pub(crate) fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr {
+        self.cx.adt_discr_for_variant(adt, variant)
+    }
+
+    /// Discriminant for a given variand index and args of a coroutine
+    pub(crate) fn coroutine_discr_for_variant(
+        &self,
+        coroutine: CoroutineDef,
+        args: &GenericArgs,
+        variant: VariantIdx,
+    ) -> Discr {
+        self.cx.coroutine_discr_for_variant(coroutine, args, variant)
+    }
+
     /// The name of a variant.
     pub(crate) fn variant_name(&self, def: VariantDef) -> Symbol {
         self.cx.variant_name(def)
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 2934af31cd5..4415cd6e2e3 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -756,6 +756,12 @@ crate_def! {
     pub CoroutineDef;
 }
 
+impl CoroutineDef {
+    pub fn discriminant_for_variant(&self, args: &GenericArgs, idx: VariantIdx) -> Discr {
+        with(|cx| cx.coroutine_discr_for_variant(*self, args, idx))
+    }
+}
+
 crate_def! {
     #[derive(Serialize)]
     pub CoroutineClosureDef;
@@ -831,6 +837,15 @@ impl AdtDef {
     pub fn repr(&self) -> ReprOptions {
         with(|cx| cx.adt_repr(*self))
     }
+
+    pub fn discriminant_for_variant(&self, idx: VariantIdx) -> Discr {
+        with(|cx| cx.adt_discr_for_variant(*self, idx))
+    }
+}
+
+pub struct Discr {
+    pub val: u128,
+    pub ty: Ty,
 }
 
 /// Definition of a variant, which can be either a struct / union field or an enum variant.