diff --git a/compiler/rustc_error_messages/locales/en-US/query_system.ftl b/compiler/rustc_error_messages/locales/en-US/query_system.ftl index 050a41fc7f9dd..b914ba52a7353 100644 --- a/compiler/rustc_error_messages/locales/en-US/query_system.ftl +++ b/compiler/rustc_error_messages/locales/en-US/query_system.ftl @@ -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_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} diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 3ca657cbca17c..b9edb757b568a 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -19,8 +19,10 @@ use rustc_query_system::query::{ force_query, QueryConfig, QueryContext, QueryDescription, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame, }; -use rustc_query_system::Value; +use rustc_query_system::{LayoutOfDepth, QueryOverflow, Value}; use rustc_serialize::Decodable; +use rustc_session::Limit; +use rustc_span::def_id::LOCAL_CRATE; use std::any::Any; use std::num::NonZeroU64; use thin_vec::ThinVec; @@ -127,6 +129,29 @@ impl QueryContext for QueryCtxt<'_> { }) }) } + + 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> { diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs index 5f57a1510aa5f..bececca7585ae 100644 --- a/compiler/rustc_query_system/src/error.rs +++ b/compiler/rustc_query_system/src/error.rs @@ -1,5 +1,6 @@ use rustc_errors::AddSubdiagnostic; -use rustc_span::Span; +use rustc_session::Limit; +use rustc_span::{Span, Symbol}; pub struct CycleStack { pub span: Span, @@ -76,17 +77,20 @@ pub struct IncrementCompilation { } #[derive(SessionDiagnostic)] +#[help] #[diag(query_system::query_overflow)] pub struct QueryOverflow { + #[primary_span] + pub span: Option, #[subdiagnostic] pub layout_of_depth: Option, + pub suggested_limit: Limit, + pub crate_name: Symbol, } #[derive(SessionSubdiagnostic)] #[note(query_system::layout_of_depth)] pub struct LayoutOfDepth { - #[primary_span] - pub span: Span, pub desc: String, pub depth: usize, } diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 8a88b5c334078..78b06f520a855 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -23,4 +23,6 @@ pub mod query; mod values; pub use error::HandleCycleError; +pub use error::LayoutOfDepth; +pub use error::QueryOverflow; pub use values::Value; diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index a5ea3a098a649..95305eabd0d34 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -160,10 +160,7 @@ impl QueryJobId { #[cold] #[inline(never)] - pub(super) fn try_find_layout_root( - &self, - query_map: QueryMap, - ) -> Option<(QueryJobInfo, usize)> { + pub 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; diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index e29e8815331ee..7a96c53b60481 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -14,7 +14,7 @@ pub use self::caches::{ mod config; 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_errors::Diagnostic; use rustc_hir::def::DefKind; @@ -123,18 +123,5 @@ pub trait QueryContext: HasDepContext { compute: impl FnOnce() -> R, ) -> R; - 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 }); - } + fn depth_limit_error(&self, job: QueryJobId); } diff --git a/src/test/ui/query-system/query_depth.rs b/src/test/ui/query-system/query_depth.rs new file mode 100644 index 0000000000000..e600c1c08e5cf --- /dev/null +++ b/src/test/ui/query-system/query_depth.rs @@ -0,0 +1,31 @@ +// build-fail + +#![recursion_limit = "64"] +type Byte = Option + >>>> >>>> + >>>> >>>> + >>>> >>>> + >>>> >>>> + >>>> >>>> + >>>> >>>> + >>>> >>>> + >>>> >>>> + >>>> >>>> + >>>> >>>> +>>>> >>>>; + +fn main() { +//~^ ERROR: queries overflow the depth limit! + println!("{}", std::mem::size_of::()); +} diff --git a/src/test/ui/query-system/query_depth.stderr b/src/test/ui/query-system/query_depth.stderr new file mode 100644 index 0000000000000..43a18b4e07455 --- /dev/null +++ b/src/test/ui/query-system/query_depth.stderr @@ -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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + +error: aborting due to previous error +