Move report_cycle.

From `rustc_query_system::query::job` to `rustc_query_impl::job`.
This commit is contained in:
Nicholas Nethercote
2026-02-10 14:05:13 +11:00
parent 923de04f6a
commit a34317e5a5
9 changed files with 120 additions and 119 deletions
+1
View File
@@ -4503,6 +4503,7 @@ dependencies = [
"rustc_middle",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_thread_pool",
"tracing",
+1
View File
@@ -16,6 +16,7 @@ rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_thread_pool = { path = "../rustc_thread_pool" }
tracing = "0.1"
+57
View File
@@ -1,3 +1,4 @@
use rustc_errors::codes::*;
use rustc_hir::limit::Limit;
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};
@@ -22,3 +23,59 @@ pub(crate) struct QueryOverflowNote {
pub desc: String,
pub depth: usize,
}
#[derive(Subdiagnostic)]
#[note("...which requires {$desc}...")]
pub(crate) struct CycleStack {
#[primary_span]
pub span: Span,
pub desc: String,
}
#[derive(Subdiagnostic)]
pub(crate) enum StackCount {
#[note("...which immediately requires {$stack_bottom} again")]
Single,
#[note("...which again requires {$stack_bottom}, completing the cycle")]
Multiple,
}
#[derive(Subdiagnostic)]
pub(crate) enum Alias {
#[note("type aliases cannot be recursive")]
#[help("consider using a struct, enum, or union instead to break the cycle")]
#[help(
"see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information"
)]
Ty,
#[note("trait aliases cannot be recursive")]
Trait,
}
#[derive(Subdiagnostic)]
#[note("cycle used when {$usage}")]
pub(crate) struct CycleUsage {
#[primary_span]
pub span: Span,
pub usage: String,
}
#[derive(Diagnostic)]
#[diag("cycle detected when {$stack_bottom}", code = E0391)]
pub(crate) struct Cycle {
#[primary_span]
pub span: Span,
pub stack_bottom: String,
#[subdiagnostic]
pub cycle_stack: Vec<CycleStack>,
#[subdiagnostic]
pub stack_count: StackCount,
#[subdiagnostic]
pub alias: Option<Alias>,
#[subdiagnostic]
pub cycle_usage: Option<CycleUsage>,
#[note(
"see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information"
)]
pub note_span: (),
}
+1 -2
View File
@@ -11,12 +11,11 @@
use rustc_query_system::query::{
ActiveKeyStatus, CycleError, CycleErrorHandling, QueryCache, QueryJob, QueryJobId, QueryLatch,
QueryMode, QueryStackDeferred, QueryStackFrame, QueryState, incremental_verify_ich,
report_cycle,
};
use rustc_span::{DUMMY_SP, Span};
use crate::dep_graph::{DepContext, DepNode, DepNodeIndex};
use crate::job::{QueryJobInfo, QueryMap, find_cycle_in_stack};
use crate::job::{QueryJobInfo, QueryMap, find_cycle_in_stack, report_cycle};
use crate::{QueryCtxt, QueryFlags, SemiDynamicQueryDispatcher};
#[inline]
+55 -1
View File
@@ -3,11 +3,13 @@
use std::sync::Arc;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::DiagCtxtHandle;
use rustc_errors::{Diag, DiagCtxtHandle};
use rustc_hir::def::DefKind;
use rustc_query_system::query::{
CycleError, QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryStackDeferred, QueryStackFrame,
QueryWaiter,
};
use rustc_session::Session;
use rustc_span::{DUMMY_SP, Span};
use crate::QueryCtxt;
@@ -444,3 +446,55 @@ pub fn print_query_stack<'tcx>(
}
count_total
}
#[inline(never)]
#[cold]
pub(crate) fn report_cycle<'a>(
sess: &'a Session,
CycleError { usage, cycle: stack }: &CycleError,
) -> Diag<'a> {
assert!(!stack.is_empty());
let span = stack[0].frame.info.default_span(stack[1 % stack.len()].span);
let mut cycle_stack = Vec::new();
use crate::error::StackCount;
let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple };
for i in 1..stack.len() {
let frame = &stack[i].frame;
let span = frame.info.default_span(stack[(i + 1) % stack.len()].span);
cycle_stack
.push(crate::error::CycleStack { span, desc: frame.info.description.to_owned() });
}
let mut cycle_usage = None;
if let Some((span, ref query)) = *usage {
cycle_usage = Some(crate::error::CycleUsage {
span: query.info.default_span(span),
usage: query.info.description.to_string(),
});
}
let alias =
if stack.iter().all(|entry| matches!(entry.frame.info.def_kind, Some(DefKind::TyAlias))) {
Some(crate::error::Alias::Ty)
} else if stack.iter().all(|entry| entry.frame.info.def_kind == Some(DefKind::TraitAlias)) {
Some(crate::error::Alias::Trait)
} else {
None
};
let cycle_diag = crate::error::Cycle {
span,
cycle_stack,
stack_bottom: stack[0].frame.info.description.to_owned(),
alias,
cycle_usage,
stack_count,
note_span: (),
};
sess.dcx().create_err(cycle_diag)
}
+3 -1
View File
@@ -11,10 +11,12 @@
use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::{self, Representability, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_query_system::query::{CycleError, report_cycle};
use rustc_query_system::query::CycleError;
use rustc_span::def_id::LocalDefId;
use rustc_span::{ErrorGuaranteed, Span};
use crate::job::report_cycle;
pub(crate) trait Value<'tcx>: Sized {
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed)
-> Self;
+1 -59
View File
@@ -1,62 +1,4 @@
use rustc_errors::codes::*;
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::Span;
#[derive(Subdiagnostic)]
#[note("...which requires {$desc}...")]
pub(crate) struct CycleStack {
#[primary_span]
pub span: Span,
pub desc: String,
}
#[derive(Subdiagnostic)]
pub(crate) enum StackCount {
#[note("...which immediately requires {$stack_bottom} again")]
Single,
#[note("...which again requires {$stack_bottom}, completing the cycle")]
Multiple,
}
#[derive(Subdiagnostic)]
pub(crate) enum Alias {
#[note("type aliases cannot be recursive")]
#[help("consider using a struct, enum, or union instead to break the cycle")]
#[help(
"see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information"
)]
Ty,
#[note("trait aliases cannot be recursive")]
Trait,
}
#[derive(Subdiagnostic)]
#[note("cycle used when {$usage}")]
pub(crate) struct CycleUsage {
#[primary_span]
pub span: Span,
pub usage: String,
}
#[derive(Diagnostic)]
#[diag("cycle detected when {$stack_bottom}", code = E0391)]
pub(crate) struct Cycle {
#[primary_span]
pub span: Span,
pub stack_bottom: String,
#[subdiagnostic]
pub cycle_stack: Vec<CycleStack>,
#[subdiagnostic]
pub stack_count: StackCount,
#[subdiagnostic]
pub alias: Option<Alias>,
#[subdiagnostic]
pub cycle_usage: Option<CycleUsage>,
#[note(
"see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information"
)]
pub note_span: (),
}
use rustc_macros::Diagnostic;
#[derive(Diagnostic)]
#[diag("internal compiler error: reentrant incremental verify failure, suppressing message")]
@@ -4,13 +4,9 @@
use std::sync::Arc;
use parking_lot::{Condvar, Mutex};
use rustc_errors::Diag;
use rustc_hir::def::DefKind;
use rustc_session::Session;
use rustc_span::Span;
use super::{QueryStackDeferred, QueryStackFrameExtra};
use crate::error::CycleStack;
use crate::query::plumbing::CycleError;
use crate::query::{QueryContext, QueryStackFrame};
@@ -163,54 +159,3 @@ pub fn extract_waiter(&self, waiter: usize) -> Arc<QueryWaiter<'tcx>> {
info.waiters.remove(waiter)
}
}
#[inline(never)]
#[cold]
pub fn report_cycle<'a>(
sess: &'a Session,
CycleError { usage, cycle: stack }: &CycleError,
) -> Diag<'a> {
assert!(!stack.is_empty());
let span = stack[0].frame.info.default_span(stack[1 % stack.len()].span);
let mut cycle_stack = Vec::new();
use crate::error::StackCount;
let stack_count = if stack.len() == 1 { StackCount::Single } else { StackCount::Multiple };
for i in 1..stack.len() {
let frame = &stack[i].frame;
let span = frame.info.default_span(stack[(i + 1) % stack.len()].span);
cycle_stack.push(CycleStack { span, desc: frame.info.description.to_owned() });
}
let mut cycle_usage = None;
if let Some((span, ref query)) = *usage {
cycle_usage = Some(crate::error::CycleUsage {
span: query.info.default_span(span),
usage: query.info.description.to_string(),
});
}
let alias =
if stack.iter().all(|entry| matches!(entry.frame.info.def_kind, Some(DefKind::TyAlias))) {
Some(crate::error::Alias::Ty)
} else if stack.iter().all(|entry| entry.frame.info.def_kind == Some(DefKind::TraitAlias)) {
Some(crate::error::Alias::Trait)
} else {
None
};
let cycle_diag = crate::error::Cycle {
span,
cycle_stack,
stack_bottom: stack[0].frame.info.description.to_owned(),
alias,
cycle_usage,
stack_count,
note_span: (),
};
sess.dcx().create_err(cycle_diag)
}
+1 -1
View File
@@ -15,7 +15,7 @@
pub use self::caches::{
DefIdCache, DefaultCache, QueryCache, QueryCacheKey, SingleCache, VecCache,
};
pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryWaiter, report_cycle};
pub use self::job::{QueryInfo, QueryJob, QueryJobId, QueryLatch, QueryWaiter};
pub use self::plumbing::*;
use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};