Skip to content

Commit 3ff1b64

Browse files
committed
Auto merge of #135167 - mzacho:depth-limit-const-eval-query, r=oli-obk
Depth limit const eval query Currently the const-eval query doesn't have a recursion limit or timeout, causing the complier to freeze in an infinite loop, see #125718. This PR depth limits the `eval_to_const_value_raw` query (with the [`recursion_limit`](https://doc.rust-lang.org/reference/attributes/limits.html) attribute) and improves the diagnostics for query overflow errors, so spans are reported for other dep kinds than `layout_of` (e.g. `eval_to_const_value_raw`). fixes #125718 fixes #114192
2 parents b4045a4 + 4b81c5b commit 3ff1b64

File tree

13 files changed

+76
-33
lines changed

13 files changed

+76
-33
lines changed

compiler/rustc_middle/src/query/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,7 @@ rustc_queries! {
12431243
"simplifying constant for the type system `{}`",
12441244
key.value.display(tcx)
12451245
}
1246+
depth_limit
12461247
cache_on_disk_if { true }
12471248
}
12481249

compiler/rustc_query_impl/src/plumbing.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use rustc_query_system::query::{
2727
QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame,
2828
force_query,
2929
};
30-
use rustc_query_system::{LayoutOfDepth, QueryOverflow};
30+
use rustc_query_system::{QueryOverflow, QueryOverflowNote};
3131
use rustc_serialize::{Decodable, Encodable};
3232
use rustc_session::Limit;
3333
use rustc_span::def_id::LOCAL_CRATE;
@@ -153,23 +153,16 @@ impl QueryContext for QueryCtxt<'_> {
153153
}
154154

155155
fn depth_limit_error(self, job: QueryJobId) {
156-
let mut span = None;
157-
let mut layout_of_depth = None;
158-
if let Some((info, depth)) =
159-
job.try_find_layout_root(self.collect_active_jobs(), dep_kinds::layout_of)
160-
{
161-
span = Some(info.job.span);
162-
layout_of_depth = Some(LayoutOfDepth { desc: info.query.description, depth });
163-
}
156+
let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());
164157

165158
let suggested_limit = match self.recursion_limit() {
166159
Limit(0) => Limit(2),
167160
limit => limit * 2,
168161
};
169162

170163
self.sess.dcx().emit_fatal(QueryOverflow {
171-
span,
172-
layout_of_depth,
164+
span: info.job.span,
165+
note: QueryOverflowNote { desc: info.query.description, depth },
173166
suggested_limit,
174167
crate_name: self.crate_name(LOCAL_CRATE),
175168
});

compiler/rustc_query_system/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ query_system_increment_compilation = internal compiler error: encountered increm
2121
query_system_increment_compilation_note1 = Please follow the instructions below to create a bug report with the provided information
2222
query_system_increment_compilation_note2 = See <https://github.com/rust-lang/rust/issues/84970> for more information
2323
24-
query_system_layout_of_depth = query depth increased by {$depth} when {$desc}
24+
query_system_overflow_note = query depth increased by {$depth} when {$desc}
2525
2626
query_system_query_overflow = queries overflow the depth limit!
2727
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)

compiler/rustc_query_system/src/error.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,16 @@ pub(crate) struct IncrementCompilation {
8282
#[diag(query_system_query_overflow)]
8383
pub struct QueryOverflow {
8484
#[primary_span]
85-
pub span: Option<Span>,
85+
pub span: Span,
8686
#[subdiagnostic]
87-
pub layout_of_depth: Option<LayoutOfDepth>,
87+
pub note: QueryOverflowNote,
8888
pub suggested_limit: Limit,
8989
pub crate_name: Symbol,
9090
}
9191

9292
#[derive(Subdiagnostic)]
93-
#[note(query_system_layout_of_depth)]
94-
pub struct LayoutOfDepth {
93+
#[note(query_system_overflow_note)]
94+
pub struct QueryOverflowNote {
9595
pub desc: String,
9696
pub depth: usize,
9797
}

compiler/rustc_query_system/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub mod ich;
1616
pub mod query;
1717
mod values;
1818

19-
pub use error::{HandleCycleError, LayoutOfDepth, QueryOverflow};
19+
pub use error::{HandleCycleError, QueryOverflow, QueryOverflowNote};
2020
pub use values::Value;
2121

2222
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

compiler/rustc_query_system/src/query/job.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_span::{DUMMY_SP, Span};
1515
use crate::dep_graph::DepContext;
1616
use crate::error::CycleStack;
1717
use crate::query::plumbing::CycleError;
18-
use crate::query::{DepKind, QueryContext, QueryStackFrame};
18+
use crate::query::{QueryContext, QueryStackFrame};
1919

2020
/// Represents a span and a query key.
2121
#[derive(Clone, Debug)]
@@ -136,20 +136,18 @@ impl QueryJobId {
136136

137137
#[cold]
138138
#[inline(never)]
139-
pub fn try_find_layout_root(
140-
&self,
141-
query_map: QueryMap,
142-
layout_of_kind: DepKind,
143-
) -> Option<(QueryJobInfo, usize)> {
144-
let mut last_layout = None;
145-
let mut current_id = Some(*self);
146-
let mut depth = 0;
139+
pub fn find_dep_kind_root(&self, query_map: QueryMap) -> (QueryJobInfo, usize) {
140+
let mut depth = 1;
141+
let info = query_map.get(&self).unwrap();
142+
let dep_kind = info.query.dep_kind;
143+
let mut current_id = info.job.parent;
144+
let mut last_layout = (info.clone(), depth);
147145

148146
while let Some(id) = current_id {
149147
let info = query_map.get(&id).unwrap();
150-
if info.query.dep_kind == layout_of_kind {
148+
if info.query.dep_kind == dep_kind {
151149
depth += 1;
152-
last_layout = Some((info.clone(), depth));
150+
last_layout = (info.clone(), depth);
153151
}
154152
current_id = info.job.parent;
155153
}

tests/ui/consts/recursive-block.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const fn foo<T>() {
2+
const { foo::<&T>() } //~ ERROR: queries overflow the depth limit!
3+
}
4+
5+
fn main () {
6+
const X: () = foo::<i32>();
7+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: queries overflow the depth limit!
2+
--> $DIR/recursive-block.rs:2:11
3+
|
4+
LL | const { foo::<&T>() }
5+
| ^^^^^^^^^^^^^^^
6+
|
7+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_block`)
8+
= note: query depth increased by 1 when computing layout of `foo<&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&i32>`
9+
10+
error: aborting due to 1 previous error
11+
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ build-fail
2+
#![recursion_limit = "7"]
3+
4+
struct Thing<T>(T);
5+
6+
impl<T> Thing<T> {
7+
const X: usize = Thing::<Option<T>>::X;
8+
}
9+
10+
fn main() {
11+
println!("{}", Thing::<i32>::X); //~ ERROR: queries overflow the depth limit!
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: queries overflow the depth limit!
2+
--> $DIR/recursive-const-in-impl.rs:11:14
3+
|
4+
LL | println!("{}", Thing::<i32>::X);
5+
| ^^^^
6+
|
7+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "14"]` attribute to your crate (`recursive_const_in_impl`)
8+
= note: query depth increased by 9 when simplifying constant for the type system `main::promoted[1]`
9+
10+
error: aborting due to 1 previous error
11+
+3-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
// FIXME(generic_const_items): This leads to a stack overflow in the compiler!
2-
//@ known-bug: unknown
3-
//@ ignore-test
1+
//@ build-fail
42

53
#![feature(generic_const_items)]
64
#![allow(incomplete_features)]
5+
#![recursion_limit = "15"]
76

87
const RECUR<T>: () = RECUR::<(T,)>;
98

109
fn main() {
11-
let _ = RECUR::<()>;
10+
let _ = RECUR::<()>; //~ ERROR: queries overflow the depth limit!
1211
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: queries overflow the depth limit!
2+
--> $DIR/recursive.rs:10:13
3+
|
4+
LL | let _ = RECUR::<()>;
5+
| ^^^^^^^^^^^
6+
|
7+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "30"]` attribute to your crate (`recursive`)
8+
= note: query depth increased by 17 when simplifying constant for the type system `RECUR`
9+
10+
error: aborting due to 1 previous error
11+

tests/ui/query-system/query_depth.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | fn main() {
55
| ^^^^^^^^^
66
|
77
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "128"]` attribute to your crate (`query_depth`)
8-
= 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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
8+
= note: query depth increased by 65 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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
99

1010
error: aborting due to 1 previous error
1111

0 commit comments

Comments
 (0)