about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSparrowLii <liyuan179@huawei.com>2022-09-15 15:45:17 +0800
committerSparrowLii <liyuan179@huawei.com>2022-09-15 16:05:44 +0800
commit89fd6ae458c96f7c3be00d93861ed3f0aa53d95b (patch)
treeefe059d3e5ba78137b72de83a97411336cc6824b
parent44506f38e079caec1b6c14e05a9b86e19544757f (diff)
downloadrust-89fd6ae458c96f7c3be00d93861ed3f0aa53d95b.tar.gz
rust-89fd6ae458c96f7c3be00d93861ed3f0aa53d95b.zip
correct span, add help message and add UI test when query depth overflows
-rw-r--r--compiler/rustc_error_messages/locales/en-US/query_system.ftl3
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs27
-rw-r--r--compiler/rustc_query_system/src/error.rs10
-rw-r--r--compiler/rustc_query_system/src/lib.rs2
-rw-r--r--compiler/rustc_query_system/src/query/job.rs5
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs17
-rw-r--r--src/test/ui/query-system/query_depth.rs31
-rw-r--r--src/test/ui/query-system/query_depth.stderr11
8 files changed, 82 insertions, 24 deletions
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 050a41fc7f9..b914ba52a73 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 3ca657cbca1..b9edb757b56 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 5f57a1510aa..bececca7585 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<Span>,
     #[subdiagnostic]
     pub layout_of_depth: Option<LayoutOfDepth>,
+    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 8a88b5c3340..78b06f520a8 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 a5ea3a098a6..95305eabd0d 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 e29e8815331..7a96c53b604 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 00000000000..e600c1c08e5
--- /dev/null
+++ b/src/test/ui/query-system/query_depth.rs
@@ -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>());
+}
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 00000000000..43a18b4e074
--- /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<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
+