Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Depth limit const eval query #135167

Merged
merged 5 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,6 +1243,7 @@ rustc_queries! {
"simplifying constant for the type system `{}`",
key.value.display(tcx)
}
depth_limit
cache_on_disk_if { true }
}

Expand Down
15 changes: 4 additions & 11 deletions compiler/rustc_query_impl/src/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use rustc_query_system::query::{
QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame,
force_query,
};
use rustc_query_system::{LayoutOfDepth, QueryOverflow};
use rustc_query_system::{QueryOverflow, QueryOverflowNote};
use rustc_serialize::{Decodable, Encodable};
use rustc_session::Limit;
use rustc_span::def_id::LOCAL_CRATE;
Expand Down Expand Up @@ -153,23 +153,16 @@ impl QueryContext for QueryCtxt<'_> {
}

fn depth_limit_error(self, job: QueryJobId) {
let mut span = None;
let mut layout_of_depth = None;
if let Some((info, depth)) =
job.try_find_layout_root(self.collect_active_jobs(), dep_kinds::layout_of)
{
span = Some(info.job.span);
layout_of_depth = Some(LayoutOfDepth { desc: info.query.description, depth });
}
let (info, depth) = job.find_dep_kind_root(self.collect_active_jobs());

let suggested_limit = match self.recursion_limit() {
Limit(0) => Limit(2),
limit => limit * 2,
};

self.sess.dcx().emit_fatal(QueryOverflow {
span,
layout_of_depth,
span: info.job.span,
note: QueryOverflowNote { desc: info.query.description, depth },
suggested_limit,
crate_name: self.crate_name(LOCAL_CRATE),
});
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_query_system/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ query_system_increment_compilation = internal compiler error: encountered increm
query_system_increment_compilation_note1 = Please follow the instructions below to create a bug report with the provided information
query_system_increment_compilation_note2 = See <https://github.com/rust-lang/rust/issues/84970> for more information
query_system_layout_of_depth = query depth increased by {$depth} when {$desc}
query_system_overflow_note = query depth increased by {$depth} when {$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}`)
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_query_system/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ pub(crate) struct IncrementCompilation {
#[diag(query_system_query_overflow)]
pub struct QueryOverflow {
#[primary_span]
pub span: Option<Span>,
pub span: Span,
#[subdiagnostic]
pub layout_of_depth: Option<LayoutOfDepth>,
pub note: QueryOverflowNote,
pub suggested_limit: Limit,
pub crate_name: Symbol,
}

#[derive(Subdiagnostic)]
#[note(query_system_layout_of_depth)]
pub struct LayoutOfDepth {
#[note(query_system_overflow_note)]
pub struct QueryOverflowNote {
pub desc: String,
pub depth: usize,
}
2 changes: 1 addition & 1 deletion compiler/rustc_query_system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod ich;
pub mod query;
mod values;

pub use error::{HandleCycleError, LayoutOfDepth, QueryOverflow};
pub use error::{HandleCycleError, QueryOverflow, QueryOverflowNote};
pub use values::Value;

rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
20 changes: 9 additions & 11 deletions compiler/rustc_query_system/src/query/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_span::{DUMMY_SP, Span};
use crate::dep_graph::DepContext;
use crate::error::CycleStack;
use crate::query::plumbing::CycleError;
use crate::query::{DepKind, QueryContext, QueryStackFrame};
use crate::query::{QueryContext, QueryStackFrame};

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

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

while let Some(id) = current_id {
let info = query_map.get(&id).unwrap();
if info.query.dep_kind == layout_of_kind {
if info.query.dep_kind == dep_kind {
depth += 1;
last_layout = Some((info.clone(), depth));
last_layout = (info.clone(), depth);
}
current_id = info.job.parent;
}
Expand Down
7 changes: 7 additions & 0 deletions tests/ui/consts/recursive-block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const fn foo<T>() {
const { foo::<&T>() } //~ ERROR: queries overflow the depth limit!
}

fn main () {
const X: () = foo::<i32>();
}
11 changes: 11 additions & 0 deletions tests/ui/consts/recursive-block.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: queries overflow the depth limit!
--> $DIR/recursive-block.rs:2:11
|
LL | const { foo::<&T>() }
| ^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`recursive_block`)
= note: query depth increased by 1 when computing layout of `foo<&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&i32>`

error: aborting due to 1 previous error

12 changes: 12 additions & 0 deletions tests/ui/consts/recursive-const-in-impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ build-fail
#![recursion_limit = "7"]

struct Thing<T>(T);

impl<T> Thing<T> {
const X: usize = Thing::<Option<T>>::X;
}

fn main() {
println!("{}", Thing::<i32>::X); //~ ERROR: queries overflow the depth limit!
}
11 changes: 11 additions & 0 deletions tests/ui/consts/recursive-const-in-impl.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: queries overflow the depth limit!
--> $DIR/recursive-const-in-impl.rs:11:14
|
LL | println!("{}", Thing::<i32>::X);
| ^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "14"]` attribute to your crate (`recursive_const_in_impl`)
= note: query depth increased by 9 when simplifying constant for the type system `main::promoted[1]`

error: aborting due to 1 previous error

7 changes: 3 additions & 4 deletions tests/ui/generic-const-items/recursive.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// FIXME(generic_const_items): This leads to a stack overflow in the compiler!
//@ known-bug: unknown
//@ ignore-test
//@ build-fail

#![feature(generic_const_items)]
#![allow(incomplete_features)]
#![recursion_limit = "15"]

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

fn main() {
let _ = RECUR::<()>;
let _ = RECUR::<()>; //~ ERROR: queries overflow the depth limit!
}
11 changes: 11 additions & 0 deletions tests/ui/generic-const-items/recursive.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: queries overflow the depth limit!
--> $DIR/recursive.rs:10:13
|
LL | let _ = RECUR::<()>;
| ^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "30"]` attribute to your crate (`recursive`)
= note: query depth increased by 17 when simplifying constant for the type system `RECUR`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be neat if we could report the query backtrace before that recursion

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Similar to cycle errors)

Copy link
Contributor Author

@mzacho mzacho Jan 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not exactly sure how this should work since the job.id never repeats in this case. I guess we could determine when the cycle is complete by finding the first parent query with job.dep_kind == eval_to_const_value_raw and a span that matches the one of the current query. What do you think about this?

Seems like a bit of a hack but I can't really think of a better solution.


error: aborting due to 1 previous error

2 changes: 1 addition & 1 deletion tests/ui/query-system/query_depth.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
= 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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`

error: aborting due to 1 previous error

Loading