From 1d6ef95075a0268e70e1868a7db03192040685d3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 10 Feb 2026 22:06:57 +1100 Subject: [PATCH] Extract `DepKindVTable` constructors to their own module --- .../rustc_query_impl/src/dep_kind_vtables.rs | 174 +++++++++++++++++ compiler/rustc_query_impl/src/lib.rs | 10 +- compiler/rustc_query_impl/src/plumbing.rs | 179 ++---------------- 3 files changed, 200 insertions(+), 163 deletions(-) create mode 100644 compiler/rustc_query_impl/src/dep_kind_vtables.rs diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs new file mode 100644 index 0000000000000..92fd9c6734d04 --- /dev/null +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -0,0 +1,174 @@ +use rustc_middle::bug; +use rustc_middle::dep_graph::DepKindVTable; +use rustc_middle::ty::TyCtxt; +use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle}; +use rustc_query_system::query::QueryCache; + +use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner}; +use crate::{QueryCtxt, QueryDispatcherUnerased, QueryFlags}; + +/// [`DepKindVTable`] constructors for special dep kinds that aren't queries. +#[expect(non_snake_case, reason = "use non-snake case to avoid collision with query names")] +mod non_query { + use super::*; + + // We use this for most things when incr. comp. is turned off. + pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: Some(|_, dep_node, _| { + bug!("force_from_dep_node: encountered {dep_node:?}") + }), + try_load_from_on_disk_cache: None, + name: &"Null", + } + } + + // We use this for the forever-red node. + pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: Some(|_, dep_node, _| { + bug!("force_from_dep_node: encountered {dep_node:?}") + }), + try_load_from_on_disk_cache: None, + name: &"Red", + } + } + + pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: Some(|tcx, _, prev_index| { + tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index); + true + }), + try_load_from_on_disk_cache: None, + name: &"SideEffect", + } + } + + pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: true, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Opaque, + force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")), + try_load_from_on_disk_cache: None, + name: &"AnonZeroDeps", + } + } + + pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: true, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"TraitSelect", + } + } + + pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Opaque, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"CompileCodegenUnit", + } + } + + pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Opaque, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"CompileMonoItem", + } + } + + pub(crate) fn Metadata<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"Metadata", + } + } +} + +/// Shared implementation of the [`DepKindVTable`] constructor for queries. +/// Called from macro-generated code for each query. +pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q, Cache, const FLAGS: QueryFlags>( + is_eval_always: bool, +) -> DepKindVTable<'tcx> +where + Q: QueryDispatcherUnerased<'tcx, Cache, FLAGS>, + Cache: QueryCache + 'tcx, +{ + let is_anon = FLAGS.is_anon; + let fingerprint_style = if is_anon { + FingerprintStyle::Opaque + } else { + >>::fingerprint_style() + }; + + if is_anon || !fingerprint_style.reconstructible() { + return DepKindVTable { + is_anon, + is_eval_always, + fingerprint_style, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: Q::NAME, + }; + } + + DepKindVTable { + is_anon, + is_eval_always, + fingerprint_style, + force_from_dep_node: Some(|tcx, dep_node, _| { + force_from_dep_node_inner(Q::query_dispatcher(tcx), tcx, dep_node) + }), + try_load_from_on_disk_cache: Some(|tcx, dep_node| { + try_load_from_on_disk_cache_inner(Q::query_dispatcher(tcx), tcx, dep_node) + }), + name: Q::NAME, + } +} + +/// Helper module containing a [`DepKindVTable`] constructor for each dep kind, +/// for use with [`rustc_middle::make_dep_kind_array`]. +/// +/// That macro will check that we gave it a constructor for every known dep kind. +mod _dep_kind_vtable_ctors { + // Re-export all of the vtable constructors for non-query and query dep kinds. + + // Non-query vtable constructors are defined in normal code. + pub(crate) use super::non_query::*; + // Query vtable constructors are defined via a macro. + pub(crate) use crate::_dep_kind_vtable_ctors_for_queries::*; +} + +pub fn make_dep_kind_vtables<'tcx>( + arena: &'tcx rustc_middle::arena::Arena<'tcx>, +) -> &'tcx [DepKindVTable<'tcx>] { + // Create an array of vtables, one for each dep kind (non-query and query). + let dep_kind_vtables: [DepKindVTable<'tcx>; _] = + rustc_middle::make_dep_kind_array!(_dep_kind_vtable_ctors); + arena.alloc_from_iter(dep_kind_vtables) +} diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 9b2078275aae5..feeb072f027af 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -12,8 +12,7 @@ use std::marker::ConstParamTy; use rustc_data_structures::sync::AtomicU64; -use rustc_middle::arena::Arena; -use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNode, DepNodeIndex}; +use rustc_middle::dep_graph::{self, DepKind, DepNode, DepNodeIndex}; use rustc_middle::queries::{ self, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; @@ -27,6 +26,7 @@ use rustc_query_system::query::{ }; use rustc_span::{ErrorGuaranteed, Span}; +pub use crate::dep_kind_vtables::make_dep_kind_vtables; pub use crate::job::{QueryJobMap, break_query_cycles, print_query_stack}; pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; use crate::plumbing::{encode_all_query_results, try_mark_green}; @@ -34,11 +34,13 @@ use crate::profiling_support::QueryKeyStringCache; pub use crate::profiling_support::alloc_self_profile_query_strings; use crate::values::Value; +#[macro_use] +mod plumbing; + +mod dep_kind_vtables; mod error; mod execution; mod job; -#[macro_use] -mod plumbing; mod profiling_support; mod values; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 9804e6b217567..12cef31f58bb2 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -13,9 +13,10 @@ use rustc_hir::def_id::DefId; use rustc_hir::limit::Limit; use rustc_index::Idx; use rustc_middle::bug; +#[expect(unused_imports, reason = "used by doc comments")] +use rustc_middle::dep_graph::DepKindVTable; use rustc_middle::dep_graph::{ - self, DepContext, DepKindVTable, DepNode, DepNodeIndex, DepsType, SerializedDepNodeIndex, - dep_kinds, + self, DepContext, DepNode, DepNodeIndex, DepsType, SerializedDepNodeIndex, dep_kinds, }; use rustc_middle::query::Key; use rustc_middle::query::on_disk_cache::{ @@ -26,7 +27,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext}; +use rustc_query_system::dep_graph::{DepNodeKey, HasDepContext}; use rustc_query_system::query::{ QueryCache, QueryContext, QueryJobId, QuerySideEffect, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, @@ -447,7 +448,8 @@ pub(crate) fn query_key_hash_verify<'tcx, C: QueryCache, const FLAGS: QueryFlags }); } -fn try_load_from_on_disk_cache<'tcx, C: QueryCache, const FLAGS: QueryFlags>( +/// Implementation of [`DepKindVTable::try_load_from_on_disk_cache`] for queries. +pub(crate) fn try_load_from_on_disk_cache_inner<'tcx, C: QueryCache, const FLAGS: QueryFlags>( query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, tcx: TyCtxt<'tcx>, dep_node: DepNode, @@ -496,7 +498,8 @@ where value } -fn force_from_dep_node<'tcx, C: QueryCache, const FLAGS: QueryFlags>( +/// Implementation of [`DepKindVTable::force_from_dep_node`] for queries. +pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache, const FLAGS: QueryFlags>( query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, tcx: TyCtxt<'tcx>, dep_node: DepNode, @@ -527,49 +530,6 @@ fn force_from_dep_node<'tcx, C: QueryCache, const FLAGS: QueryFlags>( } } -pub(crate) fn make_dep_kind_vtable_for_query< - 'tcx, - Q, - C: QueryCache + 'tcx, - const FLAGS: QueryFlags, ->( - is_eval_always: bool, -) -> DepKindVTable<'tcx> -where - Q: QueryDispatcherUnerased<'tcx, C, FLAGS>, -{ - let is_anon = FLAGS.is_anon; - let fingerprint_style = if is_anon { - FingerprintStyle::Opaque - } else { - >>::fingerprint_style() - }; - - if is_anon || !fingerprint_style.reconstructible() { - return DepKindVTable { - is_anon, - is_eval_always, - fingerprint_style, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: Q::NAME, - }; - } - - DepKindVTable { - is_anon, - is_eval_always, - fingerprint_style, - force_from_dep_node: Some(|tcx, dep_node, _| { - force_from_dep_node(Q::query_dispatcher(tcx), tcx, dep_node) - }), - try_load_from_on_disk_cache: Some(|tcx, dep_node| { - try_load_from_on_disk_cache(Q::query_dispatcher(tcx), tcx, dep_node) - }), - name: Q::NAME, - } -} - // NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros // invoked by `rustc_with_all_queries`. macro_rules! define_queries { @@ -882,119 +842,20 @@ macro_rules! define_queries { for<'tcx> fn(TyCtxt<'tcx>) ] = &[$(query_impl::$name::query_key_hash_verify),*]; - /// Module containing a named function for each dep kind (including queries) - /// that creates a `DepKindVTable`. - /// - /// Consumed via `make_dep_kind_array!` to create a list of vtables. - #[expect(non_snake_case)] - mod _dep_kind_vtable_ctors { - use super::*; - use rustc_middle::bug; - use rustc_query_system::dep_graph::FingerprintStyle; - - // We use this for most things when incr. comp. is turned off. - pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)), - try_load_from_on_disk_cache: None, - name: &"Null", - } - } - - // We use this for the forever-red node. - pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)), - try_load_from_on_disk_cache: None, - name: &"Red", - } - } + /// Declares a dep-kind vtable constructor for each query. + mod _dep_kind_vtable_ctors_for_queries { + use ::rustc_middle::dep_graph::DepKindVTable; + use $crate::dep_kind_vtables::make_dep_kind_vtable_for_query; - pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|tcx, _, prev_index| { - tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index); - true - }), - try_load_from_on_disk_cache: None, - name: &"SideEffect", - } - } - - pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: true, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Opaque, - force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")), - try_load_from_on_disk_cache: None, - name: &"AnonZeroDeps", - } - } - - pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: true, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"TraitSelect", - } - } - - pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Opaque, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"CompileCodegenUnit", - } - } - - pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Opaque, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"CompileMonoItem", - } - } - - pub(crate) fn Metadata<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"Metadata", + $( + /// `DepKindVTable` constructor for this query. + pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> { + use $crate::query_impl::$name::QueryType; + make_dep_kind_vtable_for_query::, _, _>( + is_eval_always!([$($modifiers)*]), + ) } - } - - $(pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> { - use $crate::query_impl::$name::QueryType; - $crate::plumbing::make_dep_kind_vtable_for_query::, _, _>( - is_eval_always!([$($modifiers)*]), - ) - })* - } - - pub fn make_dep_kind_vtables<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindVTable<'tcx>] { - arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(_dep_kind_vtable_ctors)) + )* } } }