add note for layout_of when query depth overflows

This commit is contained in:
SparrowLii 2022-09-14 21:00:00 +08:00
parent c3f59295fe
commit 44506f38e0
5 changed files with 52 additions and 5 deletions

View File

@ -23,3 +23,5 @@ query_system_cycle_recursive_trait_alias = trait aliases cannot be recursive
query_system_cycle_which_requires = ...which requires {$desc}... query_system_cycle_which_requires = ...which requires {$desc}...
query_system_query_overflow = queries overflow the depth limit! query_system_query_overflow = queries overflow the depth limit!
query_system_layout_of_depth = Query depth increased by {$depth} when {$desc}!

View File

@ -109,7 +109,7 @@ impl QueryContext for QueryCtxt<'_> {
// when accessing the `ImplicitCtxt`. // when accessing the `ImplicitCtxt`.
tls::with_related_context(**self, move |current_icx| { tls::with_related_context(**self, move |current_icx| {
if depth_limit && !self.recursion_limit().value_within_limit(current_icx.query_depth) { if depth_limit && !self.recursion_limit().value_within_limit(current_icx.query_depth) {
self.depth_limit_error(); self.depth_limit_error(token);
} }
// Update the `ImplicitCtxt` to point to our new query job. // Update the `ImplicitCtxt` to point to our new query job.

View File

@ -77,4 +77,16 @@ pub struct IncrementCompilation {
#[derive(SessionDiagnostic)] #[derive(SessionDiagnostic)]
#[diag(query_system::query_overflow)] #[diag(query_system::query_overflow)]
pub struct QueryOverflow; pub struct QueryOverflow {
#[subdiagnostic]
pub layout_of_depth: Option<LayoutOfDepth>,
}
#[derive(SessionSubdiagnostic)]
#[note(query_system::layout_of_depth)]
pub struct LayoutOfDepth {
#[primary_span]
pub span: Span,
pub desc: String,
pub depth: usize,
}

View File

@ -59,6 +59,7 @@ impl QueryJobId {
} }
} }
#[derive(Clone)]
pub struct QueryJobInfo { pub struct QueryJobInfo {
pub query: QueryStackFrame, pub query: QueryStackFrame,
pub job: QueryJob, pub job: QueryJob,
@ -116,10 +117,10 @@ impl QueryJob {
} }
} }
#[cfg(not(parallel_compiler))]
impl QueryJobId { impl QueryJobId {
#[cold] #[cold]
#[inline(never)] #[inline(never)]
#[cfg(not(parallel_compiler))]
pub(super) fn find_cycle_in_stack( pub(super) fn find_cycle_in_stack(
&self, &self,
query_map: QueryMap, query_map: QueryMap,
@ -156,6 +157,27 @@ impl QueryJobId {
panic!("did not find a cycle") panic!("did not find a cycle")
} }
#[cold]
#[inline(never)]
pub(super) fn try_find_layout_root(
&self,
query_map: QueryMap,
) -> Option<(QueryJobInfo, usize)> {
let mut last_layout = None;
let mut current_id = Some(*self);
let mut depth = 0;
while let Some(id) = current_id {
let info = query_map.get(&id).unwrap();
if info.query.name == "layout_of" {
depth += 1;
last_layout = Some((info.clone(), depth));
}
current_id = info.job.parent;
}
last_layout
}
} }
#[cfg(parallel_compiler)] #[cfg(parallel_compiler)]

View File

@ -123,7 +123,18 @@ pub trait QueryContext: HasDepContext {
compute: impl FnOnce() -> R, compute: impl FnOnce() -> R,
) -> R; ) -> R;
fn depth_limit_error(&self) { fn depth_limit_error(&self, job: QueryJobId) {
self.dep_context().sess().emit_fatal(crate::error::QueryOverflow); let sess = self.dep_context().sess();
let mut layout_of_depth = None;
if let Some(map) = self.try_collect_active_jobs() {
if let Some((info, depth)) = job.try_find_layout_root(map) {
layout_of_depth = Some(crate::error::LayoutOfDepth {
span: info.job.span,
desc: info.query.description,
depth,
});
}
}
sess.emit_fatal(crate::error::QueryOverflow { layout_of_depth });
} }
} }