correct span, add help message and add UI test when query depth overflows

This commit is contained in:
SparrowLii 2022-09-15 15:45:17 +08:00
parent 44506f38e0
commit 89fd6ae458
8 changed files with 82 additions and 24 deletions

View File

@ -23,5 +23,6 @@ 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!
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
query_system_layout_of_depth = Query depth increased by {$depth} when {$desc}! query_system_layout_of_depth = query depth increased by {$depth} when {$desc}

View File

@ -19,8 +19,10 @@
force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap, force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap,
QuerySideEffects, QueryStackFrame, QuerySideEffects, QueryStackFrame,
}; };
use rustc_query_system::Value; use rustc_query_system::{LayoutOfDepth, QueryOverflow, Value};
use rustc_serialize::Decodable; use rustc_serialize::Decodable;
use rustc_session::Limit;
use rustc_span::def_id::LOCAL_CRATE;
use std::any::Any; use std::any::Any;
use std::num::NonZeroU64; use std::num::NonZeroU64;
use thin_vec::ThinVec; use thin_vec::ThinVec;
@ -127,6 +129,29 @@ fn start_query<R>(
}) })
}) })
} }
fn depth_limit_error(&self, job: QueryJobId) {
let mut span = None;
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) {
span = Some(info.job.span);
layout_of_depth = Some(LayoutOfDepth { desc: info.query.description, depth });
}
}
let suggested_limit = match self.recursion_limit() {
Limit(0) => Limit(2),
limit => limit * 2,
};
self.sess.emit_fatal(QueryOverflow {
span,
layout_of_depth,
suggested_limit,
crate_name: self.crate_name(LOCAL_CRATE),
});
}
} }
impl<'tcx> QueryCtxt<'tcx> { impl<'tcx> QueryCtxt<'tcx> {

View File

@ -1,5 +1,6 @@
use rustc_errors::AddSubdiagnostic; use rustc_errors::AddSubdiagnostic;
use rustc_span::Span; use rustc_session::Limit;
use rustc_span::{Span, Symbol};
pub struct CycleStack { pub struct CycleStack {
pub span: Span, pub span: Span,
@ -76,17 +77,20 @@ pub struct IncrementCompilation {
} }
#[derive(SessionDiagnostic)] #[derive(SessionDiagnostic)]
#[help]
#[diag(query_system::query_overflow)] #[diag(query_system::query_overflow)]
pub struct QueryOverflow { pub struct QueryOverflow {
#[primary_span]
pub span: Option<Span>,
#[subdiagnostic] #[subdiagnostic]
pub layout_of_depth: Option<LayoutOfDepth>, pub layout_of_depth: Option<LayoutOfDepth>,
pub suggested_limit: Limit,
pub crate_name: Symbol,
} }
#[derive(SessionSubdiagnostic)] #[derive(SessionSubdiagnostic)]
#[note(query_system::layout_of_depth)] #[note(query_system::layout_of_depth)]
pub struct LayoutOfDepth { pub struct LayoutOfDepth {
#[primary_span]
pub span: Span,
pub desc: String, pub desc: String,
pub depth: usize, pub depth: usize,
} }

View File

@ -23,4 +23,6 @@
mod values; mod values;
pub use error::HandleCycleError; pub use error::HandleCycleError;
pub use error::LayoutOfDepth;
pub use error::QueryOverflow;
pub use values::Value; pub use values::Value;

View File

@ -160,10 +160,7 @@ pub(super) fn find_cycle_in_stack(
#[cold] #[cold]
#[inline(never)] #[inline(never)]
pub(super) fn try_find_layout_root( pub fn try_find_layout_root(&self, query_map: QueryMap) -> Option<(QueryJobInfo, usize)> {
&self,
query_map: QueryMap,
) -> Option<(QueryJobInfo, usize)> {
let mut last_layout = None; let mut last_layout = None;
let mut current_id = Some(*self); let mut current_id = Some(*self);
let mut depth = 0; let mut depth = 0;

View File

@ -14,7 +14,7 @@
mod config; mod config;
pub use self::config::{QueryConfig, QueryDescription, QueryVTable}; pub use self::config::{QueryConfig, QueryDescription, QueryVTable};
use crate::dep_graph::{DepContext, DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::Lock;
use rustc_errors::Diagnostic; use rustc_errors::Diagnostic;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -123,18 +123,5 @@ fn start_query<R>(
compute: impl FnOnce() -> R, compute: impl FnOnce() -> R,
) -> R; ) -> R;
fn depth_limit_error(&self, job: QueryJobId) { fn depth_limit_error(&self, job: QueryJobId);
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 });
}
} }

View File

@ -0,0 +1,31 @@
// build-fail
#![recursion_limit = "64"]
type Byte = Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Option<Option<Option<Option< Option<Option<Option<Option<
Box<String>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>
>>>> >>>>;
fn main() {
//~^ ERROR: queries overflow the depth limit!
println!("{}", std::mem::size_of::<Byte>());
}

View File

@ -0,0 +1,11 @@
error: queries overflow the depth limit!
--> $DIR/query_depth.rs:28:1
|
LL | fn main() {
| ^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "128"]` attribute to your crate (`query_depth`)
= note: query depth increased by 66 when computing layout of `core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<core::option::Option<alloc::boxed::Box<alloc::string::String>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
error: aborting due to previous error