Extract DepKindVTable constructors to their own module

This commit is contained in:
Zalathar 2026-02-10 22:06:57 +11:00
parent d7daac06d8
commit 1d6ef95075
3 changed files with 200 additions and 163 deletions

View file

@ -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 {
<Cache::Key as DepNodeKey<TyCtxt<'tcx>>>::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)
}

View file

@ -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;

View file

@ -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 {
<C::Key as DepNodeKey<TyCtxt<'tcx>>>::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;
/// 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;
// 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",
$(
/// `DepKindVTable` constructor for this query.
pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> {
use $crate::query_impl::$name::QueryType;
make_dep_kind_vtable_for_query::<QueryType<'tcx>, _, _>(
is_eval_always!([$($modifiers)*]),
)
}
}
// 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",
}
}
$(pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> {
use $crate::query_impl::$name::QueryType;
$crate::plumbing::make_dep_kind_vtable_for_query::<QueryType<'tcx>, _, _>(
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))
)*
}
}
}