Change how query vtables are constructed.

Currently `define_dep_nodes` produces a macro `make_dep_kind_array` that
encodes the names of non-queries followed by queries. This macro is used
by `make_dep_kind_vtables` to make the full array of vtables, by
referring to vtable constructor functions that are put into `mod
_dep_kind_vtable_ctors`. Pretty weird!

This commit takes advantage of the previous commit's changes to
`rustc_with_all_queries`, which makes both query and non-query
information available. A new call to `rustc_with_all_queries` is used to
construct the vtable array. (This moves some dep_kind_vtable code from
`plumbing.rs` to `dep_kind_vtables.rs`, which is good.) It's
straightforward now with iterator chaining, and `mod
_dep_kind_vtable_ctors` is no longer needed.
This commit is contained in:
Nicholas Nethercote
2026-02-27 13:25:01 +11:00
parent 253c6965bc
commit 40b2274f6c
3 changed files with 45 additions and 44 deletions
@@ -284,15 +284,6 @@ fn $q_name:ident($K:ty) -> $V:ty,
)*
}
) => {
#[macro_export]
macro_rules! make_dep_kind_array {
($mod:ident) => {[
$( $mod::$nq_name(), )*
$( $mod::$q_name(), )*
]};
}
/// This enum serves as an index into arrays built by `make_dep_kind_array`.
// This enum has more than u8::MAX variants so we need some kind of multi-byte
// encoding. The derived Encodable/Decodable uses leb128 encoding which is
// dense when only considering this enum. But DepKind is encoded in a larger
@@ -1,3 +1,4 @@
use rustc_middle::arena::Arena;
use rustc_middle::bug;
use rustc_middle::dep_graph::{DepKindVTable, DepNodeKey, KeyFingerprintStyle};
use rustc_middle::query::QueryCache;
@@ -133,24 +134,51 @@ pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q>(
}
}
/// 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.
macro_rules! define_dep_kind_vtables {
(
queries {
$(
$(#[$attr:meta])*
[$($modifiers:tt)*]
fn $name:ident($K:ty) -> $V:ty,
)*
}
non_queries {
$(
$(#[$nq_attr:meta])*
$nq_name:ident,
)*
}
) => {{
// The small number of non-query vtables: `Null`, `Red`, etc.
let nq_vtables = [
$(
non_query::$nq_name(),
)*
];
// 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::*;
// The large number of query vtables.
let q_vtables: [DepKindVTable<'tcx>; _] = [
$(
$crate::dep_kind_vtables::make_dep_kind_vtable_for_query::<
$crate::query_impl::$name::VTableGetter,
>(
is_anon!([$($modifiers)*]),
if_cache_on_disk!([$($modifiers)*] true false),
is_eval_always!([$($modifiers)*]),
)
),*
];
(nq_vtables, q_vtables)
}}
}
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)
// Create an array of vtables, one for each dep kind (non-query and query).
pub fn make_dep_kind_vtables<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindVTable<'tcx>] {
let (nq_vtables, q_vtables) =
rustc_middle::rustc_with_all_queries! { define_dep_kind_vtables! };
// Non-query vtables must come before query vtables, to match the order of `DepKind`.
arena.alloc_from_iter(nq_vtables.into_iter().chain(q_vtables.into_iter()))
}
-18
View File
@@ -693,23 +693,5 @@ pub fn query_key_hash_verify_all<'tcx>(tcx: TyCtxt<'tcx>) {
})
}
}
/// 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;
$(
/// `DepKindVTable` constructor for this query.
pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> {
use $crate::query_impl::$name::VTableGetter;
make_dep_kind_vtable_for_query::<VTableGetter>(
is_anon!([$($modifiers)*]),
if_cache_on_disk!([$($modifiers)*] true false),
is_eval_always!([$($modifiers)*]),
)
}
)*
}
}
}