Add a TaggedQueryKey to identify a query instance

This commit is contained in:
John Kåre Alsaker
2026-03-06 10:29:23 +01:00
parent 4efe3dc40f
commit 85967c4de4
11 changed files with 140 additions and 221 deletions
-1
View File
@@ -4575,7 +4575,6 @@ dependencies = [
"rustc_macros",
"rustc_middle",
"rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_thread_pool",
"tracing",
+5 -11
View File
@@ -7,21 +7,15 @@
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<I> {
pub struct QueryInfo<'tcx> {
/// The span corresponding to the reason for which this query was required.
pub span: Span,
pub frame: QueryStackFrame<I>,
}
impl<'tcx> QueryInfo<QueryStackDeferred<'tcx>> {
pub(crate) fn lift(&self) -> QueryInfo<QueryStackFrameExtra> {
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<QueryJobId>,
pub condvar: Condvar,
pub span: Span,
pub cycle: Mutex<Option<CycleError<QueryStackDeferred<'tcx>>>>,
pub cycle: Mutex<Option<CycleError<'tcx>>>,
}
#[derive(Clone, Debug)]
@@ -94,7 +88,7 @@ pub fn wait_on(
tcx: TyCtxt<'tcx>,
query: Option<QueryJobId>,
span: Span,
) -> Result<(), CycleError<QueryStackDeferred<'tcx>>> {
) -> Result<(), CycleError<'tcx>> {
let mut waiters_guard = self.waiters.lock();
let Some(waiters) = &mut *waiters_guard else {
return Ok(()); // already complete
+1 -1
View File
@@ -7,7 +7,7 @@
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;
+70 -20
View File
@@ -12,9 +12,9 @@
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<I = QueryStackFrameExtra> {
pub struct CycleError<'tcx> {
/// The query and related span that uses the cycle.
pub usage: Option<(Span, QueryStackFrame<I>)>,
pub cycle: Vec<QueryInfo<I>>,
}
impl<'tcx> CycleError<QueryStackDeferred<'tcx>> {
pub fn lift(&self) -> CycleError<QueryStackFrameExtra> {
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<QueryInfo<'tcx>>,
}
#[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 @@ pub fn $name(self, value: $name::ProvidedValue<'tcx>) {
}
)*
/// 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<DefKind> {
// 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<DefKind> {
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> {
$(
+3 -91
View File
@@ -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<I> {
/// 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<DefId>,
/// A def-id that is extracted from a `Ty` in a query key
pub def_id_for_ty_in_cycle: Option<DefId>,
}
impl<'tcx> QueryStackFrame<QueryStackDeferred<'tcx>> {
#[inline]
pub fn new(
info: QueryStackDeferred<'tcx>,
dep_kind: DepKind,
def_id: Option<DefId>,
def_id_for_ty_in_cycle: Option<DefId>,
) -> Self {
Self { info, def_id, dep_kind, def_id_for_ty_in_cycle }
}
pub fn lift(&self) -> QueryStackFrame<QueryStackFrameExtra> {
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<Span>,
pub def_kind: Option<DefKind>,
}
impl QueryStackFrameExtra {
#[inline]
pub fn new(description: String, span: Option<Span>, def_kind: Option<DefKind>) -> 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<dyn Fn() -> QueryStackFrameExtra + DynSync + DynSend>,
}
impl<'tcx> QueryStackDeferred<'tcx> {
pub fn new<C: Copy + DynSync + DynSend + 'tcx>(
context: C,
extract: fn(C) -> QueryStackFrameExtra,
) -> Self {
let extract: Arc<dyn Fn() -> 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")
}
}
-1
View File
@@ -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"
+6 -7
View File
@@ -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 @@ fn gather_active_jobs<'tcx, C>(
// 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, &current_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),
}
}
@@ -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<Q, T>(
fn layout_of<'tcx>(
tcx: TyCtxt<'tcx>,
cycle_error: CycleError,
cycle_error: CycleError<'tcx>,
_guar: ErrorGuaranteed,
) -> Result<TyAndLayout<'tcx>, &'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();
+31 -28
View File
@@ -7,11 +7,9 @@
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 @@ pub(crate) fn insert(&mut self, id: QueryJobId, info: QueryJobInfo<'tcx>) {
self.map.insert(id, info);
}
fn frame_of(&self, id: QueryJobId) -> &QueryStackFrame<QueryStackDeferred<'tcx>> {
fn frame_of(&self, id: QueryJobId) -> &QueryStackFrame<'tcx> {
&self.map[&id].frame
}
@@ -50,7 +48,7 @@ fn latch_of(&self, id: QueryJobId) -> Option<&QueryLatch<'tcx>> {
#[derive(Clone, Debug)]
pub(crate) struct QueryJobInfo<'tcx> {
pub(crate) frame: QueryStackFrame<QueryStackDeferred<'tcx>>,
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<QueryJobId>,
span: Span,
) -> CycleError<QueryStackDeferred<'tcx>> {
) -> 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)
}
+1 -1
View File
@@ -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};
+12 -53
View File
@@ -18,14 +18,10 @@
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<R>(
})
}
/// 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<QueryStackDeferred<'tcx>>
) -> QueryStackFrame<'tcx>
where
C: QueryCache<Key: QueryKey + DynSend + DynSync>,
QueryVTable<'tcx, C>: DynSync,
{
let kind = vtable.dep_kind;
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, 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 @@ pub(crate) fn make_query_vtable<'tcx>(incremental: bool)
}),
format_value: |value| format!("{:?}", erase::restore_val::<queries::$name::Value<'tcx>>(*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 {