From 85967c4de4fbbabf14728a0e7d1cc1c8101da1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 6 Mar 2026 10:29:23 +0100 Subject: [PATCH] Add a `TaggedQueryKey` to identify a query instance --- Cargo.lock | 1 - compiler/rustc_middle/src/query/job.rs | 16 +--- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/query/plumbing.rs | 90 ++++++++++++++---- compiler/rustc_middle/src/query/stack.rs | 94 +------------------ compiler/rustc_query_impl/Cargo.toml | 1 - compiler/rustc_query_impl/src/execution.rs | 13 ++- .../rustc_query_impl/src/from_cycle_error.rs | 18 ++-- compiler/rustc_query_impl/src/job.rs | 59 ++++++------ compiler/rustc_query_impl/src/lib.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 65 +++---------- 11 files changed, 140 insertions(+), 221 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba41143ff61d6..202e801846b8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4575,7 +4575,6 @@ dependencies = [ "rustc_macros", "rustc_middle", "rustc_serialize", - "rustc_session", "rustc_span", "rustc_thread_pool", "tracing", diff --git a/compiler/rustc_middle/src/query/job.rs b/compiler/rustc_middle/src/query/job.rs index 923eae045cae2..2747935942b55 100644 --- a/compiler/rustc_middle/src/query/job.rs +++ b/compiler/rustc_middle/src/query/job.rs @@ -7,21 +7,15 @@ use parking_lot::{Condvar, Mutex}; use rustc_span::Span; use crate::query::plumbing::CycleError; -use crate::query::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra}; +use crate::query::stack::QueryStackFrame; use crate::ty::TyCtxt; /// Represents a span and a query key. #[derive(Clone, Debug)] -pub struct QueryInfo { +pub struct QueryInfo<'tcx> { /// The span corresponding to the reason for which this query was required. pub span: Span, - pub frame: QueryStackFrame, -} - -impl<'tcx> QueryInfo> { - pub(crate) fn lift(&self) -> QueryInfo { - QueryInfo { span: self.span, frame: self.frame.lift() } - } + pub frame: QueryStackFrame<'tcx>, } /// A value uniquely identifying an active query job. @@ -74,7 +68,7 @@ pub struct QueryWaiter<'tcx> { pub query: Option, pub condvar: Condvar, pub span: Span, - pub cycle: Mutex>>>, + pub cycle: Mutex>>, } #[derive(Clone, Debug)] @@ -94,7 +88,7 @@ impl<'tcx> QueryLatch<'tcx> { tcx: TyCtxt<'tcx>, query: Option, span: Span, - ) -> Result<(), CycleError>> { + ) -> Result<(), CycleError<'tcx>> { let mut waiters_guard = self.waiters.lock(); let Some(waiters) = &mut *waiters_guard else { return Ok(()); // already complete diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ef96ebb83bff4..9876441f5218d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -7,7 +7,7 @@ pub use self::plumbing::{ ActiveKeyStatus, CycleError, CycleErrorHandling, EnsureMode, IntoQueryParam, QueryMode, QueryState, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult, }; -pub use self::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra}; +pub use self::stack::QueryStackFrame; pub use crate::queries::Providers; use crate::ty::TyCtxt; diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 33c38adcef058..1337dfc25d694 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -12,9 +12,9 @@ pub use sealed::IntoQueryParam; use crate::dep_graph::{DepKind, DepNodeIndex, SerializedDepNodeIndex}; use crate::ich::StableHashingContext; -use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables}; +use crate::queries::{ExternProviders, Providers, QueryArenas, QueryVTables, TaggedQueryKey}; use crate::query::on_disk_cache::OnDiskCache; -use crate::query::stack::{QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra}; +use crate::query::stack::QueryStackFrame; use crate::query::{QueryCache, QueryInfo, QueryJob}; use crate::ty::TyCtxt; @@ -60,19 +60,10 @@ pub enum CycleErrorHandling { } #[derive(Clone, Debug)] -pub struct CycleError { +pub struct CycleError<'tcx> { /// The query and related span that uses the cycle. - pub usage: Option<(Span, QueryStackFrame)>, - pub cycle: Vec>, -} - -impl<'tcx> CycleError> { - pub fn lift(&self) -> CycleError { - CycleError { - usage: self.usage.as_ref().map(|(span, frame)| (*span, frame.lift())), - cycle: self.cycle.iter().map(|info| info.lift()).collect(), - } - } + pub usage: Option<(Span, QueryStackFrame<'tcx>)>, + pub cycle: Vec>, } #[derive(Debug)] @@ -139,16 +130,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> { pub value_from_cycle_error: fn( tcx: TyCtxt<'tcx>, key: C::Key, - cycle_error: CycleError, + cycle_error: CycleError<'tcx>, 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 create_tagged_key: fn(C::Key) -> TaggedQueryKey<'tcx>, /// Function pointer that is called by the query methods on [`TyCtxt`] and /// friends[^1], after they have checked the in-memory cache and found no @@ -524,6 +511,69 @@ macro_rules! define_callbacks { } )* + /// Identifies a query by kind and key. This is in contrast to `QueryJobId` which is just a number. + #[allow(non_camel_case_types)] + #[derive(Clone, Debug)] + pub enum TaggedQueryKey<'tcx> { + $( + $name($name::Key<'tcx>), + )* + } + + impl<'tcx> TaggedQueryKey<'tcx> { + /// 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 fn description(&self, tcx: TyCtxt<'tcx>) -> String { + let (name, description) = ty::print::with_no_queries!(match self { + $( + TaggedQueryKey::$name(key) => (stringify!($name), _description_fns::$name(tcx, *key)), + )* + }); + if tcx.sess.verbose_internals() { + format!("{description} [{name:?}]") + } else { + description + } + } + + /// Returns the default span for this query if `span` is a dummy span. + pub fn default_span(&self, tcx: TyCtxt<'tcx>, span: Span) -> Span { + if !span.is_dummy() { + return span + } + if let TaggedQueryKey::def_span(..) = self { + // The `def_span` query is used to calculate `default_span`, + // so exit to avoid infinite recursion. + return DUMMY_SP + } + match self { + $( + TaggedQueryKey::$name(key) => crate::query::QueryKey::default_span(key, tcx), + )* + } + } + + pub fn def_kind(&self, tcx: TyCtxt<'tcx>) -> Option { + // This is used to reduce code generation as it + // can be reused for queries with the same key type. + fn inner<'tcx>(key: &impl crate::query::QueryKey, tcx: TyCtxt<'tcx>) -> Option { + key.key_as_def_id().and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id)) + } + + if let TaggedQueryKey::def_kind(..) = self { + // Try to avoid infinite recursion. + return None + } + match self { + $( + TaggedQueryKey::$name(key) => inner(key, tcx), + )* + } + } + } + /// Holds a `QueryVTable` for each query. pub struct QueryVTables<'tcx> { $( diff --git a/compiler/rustc_middle/src/query/stack.rs b/compiler/rustc_middle/src/query/stack.rs index fd80c7edd602d..d47c3523a96b4 100644 --- a/compiler/rustc_middle/src/query/stack.rs +++ b/compiler/rustc_middle/src/query/stack.rs @@ -1,106 +1,18 @@ use std::fmt::Debug; -use std::marker::PhantomData; -use std::mem::transmute; -use std::sync::Arc; -use rustc_data_structures::sync::{DynSend, DynSync}; -use rustc_hir::def::DefKind; -use rustc_span::Span; use rustc_span::def_id::DefId; use crate::dep_graph::DepKind; +use crate::queries::TaggedQueryKey; /// Description of a frame in the query stack. /// /// This is mostly used in case of cycles for error reporting. #[derive(Clone, Debug)] -pub struct QueryStackFrame { - /// This field initially stores a `QueryStackDeferred` during collection, - /// but can later be changed to `QueryStackFrameExtra` containing concrete information - /// by calling `lift`. This is done so that collecting query does not need to invoke - /// queries, instead `lift` will call queries in a more appropriate location. - pub info: I, - +pub struct QueryStackFrame<'tcx> { + pub tagged_key: TaggedQueryKey<'tcx>, pub dep_kind: DepKind, pub def_id: Option, /// A def-id that is extracted from a `Ty` in a query key pub def_id_for_ty_in_cycle: Option, } - -impl<'tcx> QueryStackFrame> { - #[inline] - pub fn new( - info: QueryStackDeferred<'tcx>, - dep_kind: DepKind, - def_id: Option, - def_id_for_ty_in_cycle: Option, - ) -> Self { - Self { info, def_id, dep_kind, def_id_for_ty_in_cycle } - } - - pub fn lift(&self) -> QueryStackFrame { - QueryStackFrame { - info: self.info.extract(), - dep_kind: self.dep_kind, - def_id: self.def_id, - def_id_for_ty_in_cycle: self.def_id_for_ty_in_cycle, - } - } -} - -#[derive(Clone, Debug)] -pub struct QueryStackFrameExtra { - pub description: String, - pub span: Option, - pub def_kind: Option, -} - -impl QueryStackFrameExtra { - #[inline] - pub fn new(description: String, span: Option, def_kind: Option) -> Self { - Self { description, span, def_kind } - } - - // FIXME(eddyb) Get more valid `Span`s on queries. - #[inline] - pub fn default_span(&self, span: Span) -> Span { - if !span.is_dummy() { - return span; - } - self.span.unwrap_or(span) - } -} - -/// Track a 'side effect' for a particular query. -/// This is used to hold a closure which can create `QueryStackFrameExtra`. -#[derive(Clone)] -pub struct QueryStackDeferred<'tcx> { - _dummy: PhantomData<&'tcx ()>, - - // `extract` may contain references to 'tcx, but we can't tell drop checking that it won't - // access it in the destructor. - extract: Arc QueryStackFrameExtra + DynSync + DynSend>, -} - -impl<'tcx> QueryStackDeferred<'tcx> { - pub fn new( - context: C, - extract: fn(C) -> QueryStackFrameExtra, - ) -> Self { - let extract: Arc QueryStackFrameExtra + DynSync + DynSend + 'tcx> = - Arc::new(move || extract(context)); - // SAFETY: The `extract` closure does not access 'tcx in its destructor as the only - // captured variable is `context` which is Copy and cannot have a destructor. - Self { _dummy: PhantomData, extract: unsafe { transmute(extract) } } - } - - pub fn extract(&self) -> QueryStackFrameExtra { - (self.extract)() - } -} - -impl<'tcx> Debug for QueryStackDeferred<'tcx> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("QueryStackDeferred") - } -} diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 449d2ed5334a8..1c3f0f98ae178 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -14,7 +14,6 @@ rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_serialize = { path = "../rustc_serialize" } -rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_thread_pool = { path = "../rustc_thread_pool" } tracing = "0.1" diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index d8dc004f1cf7a..90bbb7aad5226 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -48,7 +48,7 @@ pub fn collect_active_jobs_from_all_queries<'tcx>( let mut complete = true; for_each_query_vtable!(ALL, tcx, |query| { - let res = gather_active_jobs(query, tcx, require_complete, &mut job_map_out); + let res = gather_active_jobs(query, require_complete, &mut job_map_out); if res.is_none() { complete = false; } @@ -66,7 +66,6 @@ pub fn collect_active_jobs_from_all_queries<'tcx>( /// grep for.) fn gather_active_jobs<'tcx, C>( query: &'tcx QueryVTable<'tcx, C>, - tcx: TyCtxt<'tcx>, require_complete: bool, job_map_out: &mut QueryJobMap<'tcx>, // Out-param; job info is gathered into this map ) -> Option<()> @@ -113,7 +112,7 @@ where // Call `make_frame` while we're not holding a `state.active` lock as `make_frame` may call // queries leading to a deadlock. for (key, job) in active { - let frame = crate::plumbing::create_deferred_query_stack_frame(tcx, query, key); + let frame = crate::plumbing::create_query_stack_frame(query, key); job_map_out.insert(job.id, QueryJobInfo { frame, job }); } @@ -126,9 +125,9 @@ fn mk_cycle<'tcx, C: QueryCache>( query: &'tcx QueryVTable<'tcx, C>, tcx: TyCtxt<'tcx>, key: C::Key, - cycle_error: CycleError, + cycle_error: CycleError<'tcx>, ) -> C::Value { - let error = report_cycle(tcx.sess, &cycle_error); + let error = report_cycle(tcx, &cycle_error); match query.cycle_error_handling { CycleErrorHandling::Error => { let guar = error.emit(); @@ -231,7 +230,7 @@ fn cycle_error<'tcx, C: QueryCache>( .expect("failed to collect active queries"); let error = find_cycle_in_stack(try_execute, job_map, ¤t_query_job(), span); - (mk_cycle(query, tcx, key, error.lift()), None) + (mk_cycle(query, tcx, key, error), None) } #[inline(always)] @@ -276,7 +275,7 @@ fn wait_for_query<'tcx, C: QueryCache>( (v, Some(index)) } - Err(cycle) => (mk_cycle(query, tcx, key, cycle.lift()), None), + Err(cycle) => (mk_cycle(query, tcx, key, cycle), None), } } diff --git a/compiler/rustc_query_impl/src/from_cycle_error.rs b/compiler/rustc_query_impl/src/from_cycle_error.rs index c69d3eb9a0f05..10baaa9209d01 100644 --- a/compiler/rustc_query_impl/src/from_cycle_error.rs +++ b/compiler/rustc_query_impl/src/from_cycle_error.rs @@ -45,7 +45,11 @@ pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) { |tcx, _, cycle, guar| erase_val(layout_of(tcx, cycle, guar)); } -pub(crate) fn default<'tcx>(tcx: TyCtxt<'tcx>, cycle_error: CycleError, query_name: &str) -> ! { +pub(crate) fn default<'tcx>( + tcx: TyCtxt<'tcx>, + cycle_error: CycleError<'tcx>, + query_name: &str, +) -> ! { let Some(guar) = tcx.sess.dcx().has_errors() else { bug!( "`from_cycle_error_default` on query `{query_name}` called without errors: {:#?}", @@ -82,7 +86,7 @@ fn fn_sig<'tcx>( fn check_representability<'tcx>( tcx: TyCtxt<'tcx>, - cycle_error: CycleError, + cycle_error: CycleError<'tcx>, _guar: ErrorGuaranteed, ) -> ! { let mut item_and_field_ids = Vec::new(); @@ -91,7 +95,7 @@ fn check_representability<'tcx>( if info.frame.dep_kind == DepKind::check_representability && let Some(field_id) = info.frame.def_id && let Some(field_id) = field_id.as_local() - && let Some(DefKind::Field) = info.frame.info.def_kind + && let Some(DefKind::Field) = info.frame.tagged_key.def_kind(tcx) { let parent_id = tcx.parent(field_id.to_def_id()); let item_id = match tcx.def_kind(parent_id) { @@ -118,7 +122,7 @@ fn check_representability<'tcx>( fn variances_of<'tcx>( tcx: TyCtxt<'tcx>, - cycle_error: CycleError, + cycle_error: CycleError<'tcx>, _guar: ErrorGuaranteed, ) -> &'tcx [ty::Variance] { search_for_cycle_permutation( @@ -164,7 +168,7 @@ fn search_for_cycle_permutation( fn layout_of<'tcx>( tcx: TyCtxt<'tcx>, - cycle_error: CycleError, + cycle_error: CycleError<'tcx>, _guar: ErrorGuaranteed, ) -> Result, &'tcx ty::layout::LayoutError<'tcx>> { let diag = search_for_cycle_permutation( @@ -205,7 +209,7 @@ fn layout_of<'tcx>( continue; }; let frame_span = - info.frame.info.default_span(cycle[(i + 1) % cycle.len()].span); + info.frame.tagged_key.default_span(tcx, cycle[(i + 1) % cycle.len()].span); if frame_span.is_dummy() { continue; } @@ -239,7 +243,7 @@ fn layout_of<'tcx>( ControlFlow::Continue(()) } }, - || report_cycle(tcx.sess, &cycle_error), + || report_cycle(tcx, &cycle_error), ); let guar = diag.emit(); diff --git a/compiler/rustc_query_impl/src/job.rs b/compiler/rustc_query_impl/src/job.rs index 01f36d06c0472..ae32ad01b1578 100644 --- a/compiler/rustc_query_impl/src/job.rs +++ b/compiler/rustc_query_impl/src/job.rs @@ -7,11 +7,9 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{Diag, DiagCtxtHandle}; use rustc_hir::def::DefKind; use rustc_middle::query::{ - CycleError, QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryStackDeferred, QueryStackFrame, - QueryWaiter, + CycleError, QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryStackFrame, QueryWaiter, }; use rustc_middle::ty::TyCtxt; -use rustc_session::Session; use rustc_span::{DUMMY_SP, Span}; use crate::execution::collect_active_jobs_from_all_queries; @@ -31,7 +29,7 @@ impl<'tcx> QueryJobMap<'tcx> { self.map.insert(id, info); } - fn frame_of(&self, id: QueryJobId) -> &QueryStackFrame> { + fn frame_of(&self, id: QueryJobId) -> &QueryStackFrame<'tcx> { &self.map[&id].frame } @@ -50,7 +48,7 @@ impl<'tcx> QueryJobMap<'tcx> { #[derive(Clone, Debug)] pub(crate) struct QueryJobInfo<'tcx> { - pub(crate) frame: QueryStackFrame>, + pub(crate) frame: QueryStackFrame<'tcx>, pub(crate) job: QueryJob<'tcx>, } @@ -59,7 +57,7 @@ pub(crate) fn find_cycle_in_stack<'tcx>( job_map: QueryJobMap<'tcx>, current_job: &Option, span: Span, -) -> CycleError> { +) -> CycleError<'tcx> { // Find the waitee amongst `current_job` parents let mut cycle = Vec::new(); let mut current_job = Option::clone(current_job); @@ -395,12 +393,12 @@ pub fn print_query_stack<'tcx>( let Some(query_info) = job_map.map.get(&query) else { break; }; - let query_extra = query_info.frame.info.extract(); + let description = query_info.frame.tagged_key.description(tcx); if Some(count_printed) < limit_frames || limit_frames.is_none() { // Only print to stderr as many stack frames as `num_frames` when present. dcx.struct_failure_note(format!( "#{} [{:?}] {}", - count_printed, query_info.frame.dep_kind, query_extra.description + count_printed, query_info.frame.dep_kind, description )) .with_span(query_info.job.span) .emit(); @@ -411,7 +409,7 @@ pub fn print_query_stack<'tcx>( let _ = writeln!( file, "#{} [{:?}] {}", - count_total, query_info.frame.dep_kind, query_extra.description + count_total, query_info.frame.dep_kind, description ); } @@ -427,18 +425,18 @@ pub fn print_query_stack<'tcx>( #[inline(never)] #[cold] -pub(crate) fn report_cycle<'a>( - sess: &'a Session, - CycleError { usage, cycle: stack }: &CycleError, -) -> Diag<'a> { +pub(crate) fn report_cycle<'tcx>( + tcx: TyCtxt<'tcx>, + CycleError { usage, cycle: stack }: &CycleError<'tcx>, +) -> Diag<'tcx> { assert!(!stack.is_empty()); - let span = stack[0].frame.info.default_span(stack[1 % stack.len()].span); + let span = stack[0].frame.tagged_key.default_span(tcx, stack[1 % stack.len()].span); let mut cycle_stack = Vec::new(); use crate::error::StackCount; - let stack_bottom = stack[0].frame.info.description.to_owned(); + let stack_bottom = stack[0].frame.tagged_key.description(tcx); let stack_count = if stack.len() == 1 { StackCount::Single { stack_bottom: stack_bottom.clone() } } else { @@ -447,27 +445,32 @@ pub(crate) fn report_cycle<'a>( for i in 1..stack.len() { let frame = &stack[i].frame; - let span = frame.info.default_span(stack[(i + 1) % stack.len()].span); + let span = frame.tagged_key.default_span(tcx, stack[(i + 1) % stack.len()].span); cycle_stack - .push(crate::error::CycleStack { span, desc: frame.info.description.to_owned() }); + .push(crate::error::CycleStack { span, desc: frame.tagged_key.description(tcx) }); } let mut cycle_usage = None; if let Some((span, ref query)) = *usage { cycle_usage = Some(crate::error::CycleUsage { - span: query.info.default_span(span), - usage: query.info.description.to_string(), + span: query.tagged_key.default_span(tcx, span), + usage: query.tagged_key.description(tcx), }); } - let alias = - if stack.iter().all(|entry| matches!(entry.frame.info.def_kind, Some(DefKind::TyAlias))) { - Some(crate::error::Alias::Ty) - } else if stack.iter().all(|entry| entry.frame.info.def_kind == Some(DefKind::TraitAlias)) { - Some(crate::error::Alias::Trait) - } else { - None - }; + let alias = if stack + .iter() + .all(|entry| matches!(entry.frame.tagged_key.def_kind(tcx), Some(DefKind::TyAlias))) + { + Some(crate::error::Alias::Ty) + } else if stack + .iter() + .all(|entry| entry.frame.tagged_key.def_kind(tcx) == Some(DefKind::TraitAlias)) + { + Some(crate::error::Alias::Trait) + } else { + None + }; let cycle_diag = crate::error::Cycle { span, @@ -479,5 +482,5 @@ pub(crate) fn report_cycle<'a>( note_span: (), }; - sess.dcx().create_err(cycle_diag) + tcx.sess.dcx().create_err(cycle_diag) } diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 41642f66967da..aaf9c78feb7f3 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -10,7 +10,7 @@ use rustc_data_structures::sync::AtomicU64; use rustc_middle::dep_graph; -use rustc_middle::queries::{self, ExternProviders, Providers}; +use rustc_middle::queries::{self, ExternProviders, Providers, TaggedQueryKey}; use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_middle::query::plumbing::{QuerySystem, QueryVTable}; use rustc_middle::query::{AsLocalQueryKey, QueryCache, QueryMode}; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 78d5fd3de1f00..0a84a8b23c076 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -18,14 +18,10 @@ use rustc_middle::query::on_disk_cache::{ AbsoluteBytePos, CacheDecoder, CacheEncoder, EncodedDepNodeIndex, }; use rustc_middle::query::plumbing::QueryVTable; -use rustc_middle::query::{ - QueryCache, QueryJobId, QueryKey, QueryMode, QueryStackDeferred, QueryStackFrame, - QueryStackFrameExtra, erase, -}; +use rustc_middle::query::{QueryCache, QueryJobId, QueryKey, QueryMode, QueryStackFrame, erase}; +use rustc_middle::ty::TyCtxt; 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_serialize::{Decodable, Encodable}; use rustc_span::DUMMY_SP; use rustc_span::def_id::LOCAL_CRATE; @@ -47,7 +43,7 @@ fn depth_limit_error<'tcx>(tcx: TyCtxt<'tcx>, job: QueryJobId) { tcx.sess.dcx().emit_fatal(QueryOverflow { span: info.job.span, - note: QueryOverflowNote { desc: info.frame.info.extract().description, depth }, + note: QueryOverflowNote { desc: info.frame.tagged_key.description(tcx), depth }, suggested_limit, crate_name: tcx.crate_name(LOCAL_CRATE), }); @@ -90,60 +86,23 @@ pub(crate) fn start_query( }) } -/// 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: QueryKey, -{ - let def_id = key.key_as_def_id(); - - // If reduced queries are requested, we may be printing a query stack due - // to a panic. Avoid using `default_span` and `def_kind` in that case. - let reduce_queries = with_reduced_queries(); - - // Avoid calling queries while formatting the description - let description = ty::print::with_no_queries!((vtable.description_fn)(tcx, key)); - let description = if tcx.sess.verbose_internals() { - format!("{description} [{name:?}]", name = vtable.name) - } else { - description - }; - let span = if vtable.dep_kind == DepKind::def_span || reduce_queries { - // The `def_span` query is used to calculate `default_span`, - // so exit to avoid infinite recursion. - None - } else { - Some(key.default_span(tcx)) - }; - - let def_kind = if vtable.dep_kind == DepKind::def_kind || reduce_queries { - // Try to avoid infinite recursion. - None - } else { - def_id.and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id)) - }; - QueryStackFrameExtra::new(description, span, def_kind) -} - -pub(crate) fn create_deferred_query_stack_frame<'tcx, C>( - tcx: TyCtxt<'tcx>, +pub(crate) fn create_query_stack_frame<'tcx, C>( vtable: &'tcx QueryVTable<'tcx, C>, key: C::Key, -) -> QueryStackFrame> +) -> QueryStackFrame<'tcx> where C: QueryCache, QueryVTable<'tcx, C>: DynSync, { - let kind = vtable.dep_kind; - 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, def_id, def_id_for_ty_in_cycle) + QueryStackFrame { + tagged_key: (vtable.create_tagged_key)(key), + dep_kind: vtable.dep_kind, + def_id, + def_id_for_ty_in_cycle, + } } pub(crate) fn encode_all_query_results<'tcx>( @@ -500,7 +459,7 @@ macro_rules! define_queries { }), format_value: |value| format!("{:?}", erase::restore_val::>(*value)), - description_fn: $crate::queries::_description_fns::$name, + create_tagged_key: TaggedQueryKey::$name, execute_query_fn: if incremental { query_impl::$name::execute_query_incr::__rust_end_short_backtrace } else {