Move report_cycle to rustc_query_system.
The call to `ty::print::with_forced_impl_filename_line` is done when constructing the description, at the construction of the QueryStackFrame.
This commit is contained in:
parent
3897395787
commit
c26d965714
5 changed files with 54 additions and 64 deletions
|
@ -3,10 +3,10 @@
|
|||
use crate::dep_graph::DepNode;
|
||||
use crate::dep_graph::SerializedDepNodeIndex;
|
||||
use crate::query::caches::QueryCache;
|
||||
use crate::query::plumbing::CycleError;
|
||||
use crate::query::{QueryCacheStore, QueryContext, QueryState};
|
||||
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_errors::DiagnosticBuilder;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub(crate) struct QueryVtable<CTX: QueryContext, K, V> {
|
|||
pub compute: fn(CTX, K) -> V,
|
||||
|
||||
pub hash_result: fn(&mut CTX::StableHashingContext, &V) -> Option<Fingerprint>,
|
||||
pub handle_cycle_error: fn(CTX, CycleError) -> V,
|
||||
pub handle_cycle_error: fn(CTX, DiagnosticBuilder<'_>) -> V,
|
||||
pub cache_on_disk: fn(CTX, &K, Option<&V>) -> bool,
|
||||
pub try_load_from_disk: fn(CTX, SerializedDepNodeIndex) -> Option<V>,
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ impl<CTX: QueryContext, K, V> QueryVtable<CTX, K, V> {
|
|||
(self.hash_result)(hcx, value)
|
||||
}
|
||||
|
||||
pub(crate) fn handle_cycle_error(&self, tcx: CTX, error: CycleError) -> V {
|
||||
(self.handle_cycle_error)(tcx, error)
|
||||
pub(crate) fn handle_cycle_error(&self, tcx: CTX, diag: DiagnosticBuilder<'_>) -> V {
|
||||
(self.handle_cycle_error)(tcx, diag)
|
||||
}
|
||||
|
||||
pub(crate) fn cache_on_disk(&self, tcx: CTX, key: &K, value: Option<&V>) -> bool {
|
||||
|
@ -90,7 +90,7 @@ pub trait QueryAccessors<CTX: QueryContext>: QueryConfig {
|
|||
result: &Self::Value,
|
||||
) -> Option<Fingerprint>;
|
||||
|
||||
fn handle_cycle_error(tcx: CTX, error: CycleError) -> Self::Value;
|
||||
fn handle_cycle_error(tcx: CTX, diag: DiagnosticBuilder<'_>) -> Self::Value;
|
||||
}
|
||||
|
||||
pub trait QueryDescription<CTX: QueryContext>: QueryAccessors<CTX> {
|
||||
|
|
|
@ -2,6 +2,8 @@ use crate::query::plumbing::CycleError;
|
|||
use crate::query::QueryStackFrame;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
@ -590,3 +592,37 @@ pub fn deadlock<CTX: QueryContext>(tcx: CTX, registry: &rayon_core::Registry) {
|
|||
|
||||
on_panic.disable();
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
pub(crate) fn report_cycle<'a>(
|
||||
sess: &'a Session,
|
||||
CycleError { usage, cycle: stack }: CycleError,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
assert!(!stack.is_empty());
|
||||
|
||||
let fix_span = |span: Span, query: &QueryStackFrame| {
|
||||
sess.source_map().guess_head_span(query.default_span(span))
|
||||
};
|
||||
|
||||
let span = fix_span(stack[1 % stack.len()].span, &stack[0].query);
|
||||
let mut err =
|
||||
struct_span_err!(sess, span, E0391, "cycle detected when {}", stack[0].query.description);
|
||||
|
||||
for i in 1..stack.len() {
|
||||
let query = &stack[i].query;
|
||||
let span = fix_span(stack[(i + 1) % stack.len()].span, query);
|
||||
err.span_note(span, &format!("...which requires {}...", query.description));
|
||||
}
|
||||
|
||||
err.note(&format!(
|
||||
"...which again requires {}, completing the cycle",
|
||||
stack[0].query.description
|
||||
));
|
||||
|
||||
if let Some((span, query)) = usage {
|
||||
err.span_note(fix_span(span, &query), &format!("cycle used when {}", query.description));
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ use crate::dep_graph::{DepContext, DepKind, DepNode};
|
|||
use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
|
||||
use crate::query::caches::QueryCache;
|
||||
use crate::query::config::{QueryDescription, QueryVtable, QueryVtableExt};
|
||||
use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId};
|
||||
use crate::query::job::{
|
||||
report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryShardJobId,
|
||||
};
|
||||
use crate::query::{QueryContext, QueryMap, QueryStackFrame};
|
||||
|
||||
#[cfg(not(parallel_compiler))]
|
||||
|
@ -245,6 +247,7 @@ where
|
|||
&tcx.current_query_job(),
|
||||
span,
|
||||
);
|
||||
let error = report_cycle(tcx.dep_context().sess(), error);
|
||||
let value = query.handle_cycle_error(tcx, error);
|
||||
cache.cache.store_nocache(value)
|
||||
}));
|
||||
|
@ -256,6 +259,7 @@ where
|
|||
let result = latch.wait_on(tcx.current_query_job(), span);
|
||||
|
||||
if let Err(cycle) = result {
|
||||
let cycle = report_cycle(tcx.dep_context().sess(), cycle);
|
||||
let value = query.handle_cycle_error(tcx, cycle);
|
||||
let value = cache.cache.store_nocache(value);
|
||||
return TryGetJob::Cycle(value);
|
||||
|
@ -352,7 +356,7 @@ where
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CycleError {
|
||||
pub(crate) struct CycleError {
|
||||
/// The query and related span that uses the cycle.
|
||||
pub usage: Option<(Span, QueryStackFrame)>,
|
||||
pub cycle: Vec<QueryInfo>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue