diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 5d7204f7a30cb..adcf4e00241e9 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -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 } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index b8f1fe9ec20b0..abb02caef25d8 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -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 { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a28bbeccc0785..bce685cb9a6a2 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -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> + '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> { - let def_id = key.key_as_def_id(); + vtable: &'tcx QueryVTable<'tcx, Cache>, + key: Cache::Key, +) -> QueryStackFrame> +where + Cache: QueryCache, + Cache::Key: Key + DynSend + DynSync + for<'a> HashStable> + '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::() }); - 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 = key.key_as_def_id(); + let def_id_for_ty_in_cycle: Option = 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::>(*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.