Rollup merge of #152153 - Zalathar:descs, r=nnethercote

Incorporate query description functions into `QueryVTable`

Putting a `desc` function in each query vtable reduces the amount of parameter juggling required when creating query stack frames, because almost all of the necessary information can be found in the vtable.

There should be no change to compiler output.
This commit is contained in:
Jonathan Brouwer 2026-02-05 12:16:58 +01:00 committed by GitHub
commit ce3df42e35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 47 additions and 34 deletions

View file

@ -429,7 +429,14 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
$macro!(#feedable_queries);
}
}
pub mod descs {
/// Functions that format a human-readable description of each query
/// and its key, as specified by the `desc` query modifier.
///
/// (The leading `_` avoids collisions with actual query names when
/// expanded in `rustc_middle::queries`, and makes this macro-generated
/// module easier to search for.)
pub mod _description_fns {
use super::*;
#query_description_stream
}

View file

@ -32,7 +32,8 @@ pub type IsLoadableFromDiskFn<'tcx, Key> =
/// Stores function pointers and other metadata for a particular query.
///
/// Used indirectly by query plumbing in `rustc_query_system`, via a trait.
/// Used indirectly by query plumbing in `rustc_query_system` via a trait,
/// and also used directly by query plumbing in `rustc_query_impl`.
pub struct QueryVTable<'tcx, C: QueryCache> {
pub name: &'static str,
pub eval_always: bool,
@ -52,6 +53,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
pub value_from_cycle_error:
fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
pub format_value: fn(&C::Value) -> String,
/// Formats a human-readable description of this query and its key, as
/// specified by the `desc` query modifier.
///
/// Used when reporting query cycle errors and similar problems.
pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
}
pub struct QuerySystemFns {

View file

@ -9,17 +9,18 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_data_structures::unord::UnordMap;
use rustc_hashes::Hash64;
use rustc_hir::def_id::DefId;
use rustc_hir::limit::Limit;
use rustc_index::Idx;
use rustc_middle::bug;
use rustc_middle::dep_graph::{
self, DepContext, DepKind, DepKindVTable, DepNode, DepNodeIndex, SerializedDepNodeIndex,
dep_kinds,
self, DepContext, DepKindVTable, DepNode, DepNodeIndex, SerializedDepNodeIndex, dep_kinds,
};
use rustc_middle::query::Key;
use rustc_middle::query::on_disk_cache::{
AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex,
};
use rustc_middle::query::plumbing::QueryVTable;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::print::with_reduced_queries;
use rustc_middle::ty::tls::{self, ImplicitCtxt};
@ -312,15 +313,14 @@ macro_rules! should_ever_cache_on_disk {
};
}
fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>(
(tcx, key, kind, name, do_describe): (
TyCtxt<'tcx>,
K,
DepKind,
&'static str,
fn(TyCtxt<'tcx>, K) -> String,
),
) -> QueryStackFrameExtra {
/// The deferred part of a deferred query stack frame.
fn mk_query_stack_frame_extra<'tcx, Cache>(
(tcx, vtable, key): (TyCtxt<'tcx>, &'tcx QueryVTable<'tcx, Cache>, Cache::Key),
) -> QueryStackFrameExtra
where
Cache: QueryCache,
Cache::Key: Key,
{
let def_id = key.key_as_def_id();
// If reduced queries are requested, we may be printing a query stack due
@ -328,13 +328,13 @@ fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>(
let reduce_queries = with_reduced_queries();
// Avoid calling queries while formatting the description
let description = ty::print::with_no_queries!(do_describe(tcx, key));
let description = ty::print::with_no_queries!((vtable.description_fn)(tcx, key));
let description = if tcx.sess.verbose_internals() {
format!("{description} [{name:?}]")
format!("{description} [{name:?}]", name = vtable.name)
} else {
description
};
let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries {
let span = if vtable.dep_kind == dep_graph::dep_kinds::def_span || reduce_queries {
// The `def_span` query is used to calculate `default_span`,
// so exit to avoid infinite recursion.
None
@ -342,7 +342,7 @@ fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>(
Some(key.default_span(tcx))
};
let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries {
let def_kind = if vtable.dep_kind == dep_graph::dep_kinds::def_kind || reduce_queries {
// Try to avoid infinite recursion.
None
} else {
@ -351,17 +351,16 @@ fn mk_query_stack_frame_extra<'tcx, K: Key + Copy + 'tcx>(
QueryStackFrameExtra::new(description, span, def_kind)
}
pub(crate) fn create_query_frame<
'tcx,
K: Copy + DynSend + DynSync + Key + for<'a> HashStable<StableHashingContext<'a>> + 'tcx,
>(
pub(crate) fn create_deferred_query_stack_frame<'tcx, Cache>(
tcx: TyCtxt<'tcx>,
do_describe: fn(TyCtxt<'tcx>, K) -> String,
key: K,
kind: DepKind,
name: &'static str,
) -> QueryStackFrame<QueryStackDeferred<'tcx>> {
let def_id = key.key_as_def_id();
vtable: &'tcx QueryVTable<'tcx, Cache>,
key: Cache::Key,
) -> QueryStackFrame<QueryStackDeferred<'tcx>>
where
Cache: QueryCache,
Cache::Key: Key + DynSend + DynSync + for<'a> HashStable<StableHashingContext<'a>> + 'tcx,
{
let kind = vtable.dep_kind;
let hash = tcx.with_stable_hashing_context(|mut hcx| {
let mut hasher = StableHasher::new();
@ -369,11 +368,11 @@ pub(crate) fn create_query_frame<
key.hash_stable(&mut hcx, &mut hasher);
hasher.finish::<Hash64>()
});
let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle();
let info =
QueryStackDeferred::new((tcx, key, kind, name, do_describe), mk_query_stack_frame_extra);
let def_id: Option<DefId> = key.key_as_def_id();
let def_id_for_ty_in_cycle: Option<DefId> = key.def_id_for_ty_in_cycle();
let info = QueryStackDeferred::new((tcx, vtable, key), mk_query_stack_frame_extra);
QueryStackFrame::new(info, kind, hash, def_id, def_id_for_ty_in_cycle)
}
@ -697,6 +696,7 @@ macro_rules! define_queries {
},
hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]),
format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*value)),
description_fn: $crate::queries::_description_fns::$name,
}
}
@ -742,10 +742,9 @@ macro_rules! define_queries {
qmap: &mut QueryMap<'tcx>,
require_complete: bool,
) -> Option<()> {
let make_frame = |tcx, key| {
let kind = rustc_middle::dep_graph::dep_kinds::$name;
let name = stringify!($name);
$crate::plumbing::create_query_frame(tcx, queries::descs::$name, key, kind, name)
let make_frame = |tcx: TyCtxt<'tcx>, key| {
let vtable = &tcx.query_system.query_vtables.$name;
$crate::plumbing::create_deferred_query_stack_frame(tcx, vtable, key)
};
// Call `gather_active_jobs_inner` to do the actual work.