summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_query_system
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:11:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:12:43 +0000
commitcf94bdc0742c13e2a0cac864c478b8626b266e1b (patch)
tree044670aa50cc5e2b4229aa0b6b3df6676730c0a6 /compiler/rustc_query_system
parentAdding debian version 1.65.0+dfsg1-2. (diff)
downloadrustc-cf94bdc0742c13e2a0cac864c478b8626b266e1b.tar.xz
rustc-cf94bdc0742c13e2a0cac864c478b8626b266e1b.zip
Merging upstream version 1.66.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_query_system')
-rw-r--r--compiler/rustc_query_system/Cargo.toml1
-rw-r--r--compiler/rustc_query_system/src/dep_graph/dep_node.rs73
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs45
-rw-r--r--compiler/rustc_query_system/src/error.rs73
-rw-r--r--compiler/rustc_query_system/src/ich/hcx.rs11
-rw-r--r--compiler/rustc_query_system/src/lib.rs5
-rw-r--r--compiler/rustc_query_system/src/query/config.rs2
-rw-r--r--compiler/rustc_query_system/src/query/job.rs33
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs15
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs11
-rw-r--r--compiler/rustc_query_system/src/values.rs5
11 files changed, 210 insertions, 64 deletions
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index d7599a56c..faddad741 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -4,7 +4,6 @@ version = "0.0.0"
edition = "2021"
[lib]
-doctest = false
[dependencies]
parking_lot = "0.11"
diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index 162c274d8..5c6ce0556 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -47,6 +47,7 @@ use crate::ich::StableHashingContext;
use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
+use rustc_hir::definitions::DefPathHash;
use std::fmt;
use std::hash::Hash;
@@ -88,6 +89,17 @@ impl<K: DepKind> DepNode<K> {
dep_node
}
+
+ /// Construct a DepNode from the given DepKind and DefPathHash. This
+ /// method will assert that the given DepKind actually requires a
+ /// single DefId/DefPathHash parameter.
+ pub fn from_def_path_hash<Ctxt>(tcx: Ctxt, def_path_hash: DefPathHash, kind: K) -> Self
+ where
+ Ctxt: super::DepContext<DepKind = K>,
+ {
+ debug_assert!(tcx.fingerprint_style(kind) == FingerprintStyle::DefPathHash);
+ DepNode { kind, hash: def_path_hash.0.into() }
+ }
}
impl<K: DepKind> fmt::Debug for DepNode<K> {
@@ -149,6 +161,67 @@ where
}
}
+/// This struct stores metadata about each DepKind.
+///
+/// Information is retrieved by indexing the `DEP_KINDS` array using the integer value
+/// of the `DepKind`. Overall, this allows to implement `DepContext` using this manual
+/// jump table instead of large matches.
+pub struct DepKindStruct<CTX: DepContext> {
+ /// Anonymous queries cannot be replayed from one compiler invocation to the next.
+ /// When their result is needed, it is recomputed. They are useful for fine-grained
+ /// dependency tracking, and caching within one compiler invocation.
+ pub is_anon: bool,
+
+ /// Eval-always queries do not track their dependencies, and are always recomputed, even if
+ /// their inputs have not changed since the last compiler invocation. The result is still
+ /// cached within one compiler invocation.
+ pub is_eval_always: bool,
+
+ /// Whether the query key can be recovered from the hashed fingerprint.
+ /// See [DepNodeParams] trait for the behaviour of each key type.
+ pub fingerprint_style: FingerprintStyle,
+
+ /// The red/green evaluation system will try to mark a specific DepNode in the
+ /// dependency graph as green by recursively trying to mark the dependencies of
+ /// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode`
+ /// where we don't know if it is red or green and we therefore actually have
+ /// to recompute its value in order to find out. Since the only piece of
+ /// information that we have at that point is the `DepNode` we are trying to
+ /// re-evaluate, we need some way to re-run a query from just that. This is what
+ /// `force_from_dep_node()` implements.
+ ///
+ /// In the general case, a `DepNode` consists of a `DepKind` and an opaque
+ /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
+ /// is usually constructed by computing a stable hash of the query-key that the
+ /// `DepNode` corresponds to. Consequently, it is not in general possible to go
+ /// back from hash to query-key (since hash functions are not reversible). For
+ /// this reason `force_from_dep_node()` is expected to fail from time to time
+ /// because we just cannot find out, from the `DepNode` alone, what the
+ /// corresponding query-key is and therefore cannot re-run the query.
+ ///
+ /// The system deals with this case letting `try_mark_green` fail which forces
+ /// the root query to be re-evaluated.
+ ///
+ /// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
+ /// Fortunately, we can use some contextual information that will allow us to
+ /// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
+ /// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a
+ /// valid `DefPathHash`. Since we also always build a huge table that maps every
+ /// `DefPathHash` in the current codebase to the corresponding `DefId`, we have
+ /// everything we need to re-run the query.
+ ///
+ /// Take the `mir_promoted` query as an example. Like many other queries, it
+ /// just has a single parameter: the `DefId` of the item it will compute the
+ /// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode`
+ /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
+ /// is actually a `DefPathHash`, and can therefore just look up the corresponding
+ /// `DefId` in `tcx.def_path_hash_to_def_id`.
+ pub force_from_dep_node: Option<fn(tcx: CTX, dep_node: DepNode<CTX::DepKind>) -> bool>,
+
+ /// Invoke a query to put the on-disk cached value in memory.
+ pub try_load_from_on_disk_cache: Option<fn(CTX, DepNode<CTX::DepKind>)>,
+}
+
/// A "work product" corresponds to a `.o` (or other) file that we
/// save in between runs. These IDs do not have a `DefId` but rather
/// some independent path or string that persists between runs without
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 342d95ca4..da2075fd5 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -4,7 +4,7 @@ mod graph;
mod query;
mod serialized;
-pub use dep_node::{DepNode, DepNodeParams, WorkProductId};
+pub use dep_node::{DepKindStruct, DepNode, DepNodeParams, WorkProductId};
pub use graph::{
hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, TaskDepsRef, WorkProduct,
};
@@ -34,16 +34,43 @@ pub trait DepContext: Copy {
/// Access the compiler session.
fn sess(&self) -> &Session;
- /// Return whether this kind always require evaluation.
- fn is_eval_always(&self, kind: Self::DepKind) -> bool;
+ fn dep_kind_info(&self, dep_node: Self::DepKind) -> &DepKindStruct<Self>;
- fn fingerprint_style(&self, kind: Self::DepKind) -> FingerprintStyle;
+ #[inline(always)]
+ fn fingerprint_style(&self, kind: Self::DepKind) -> FingerprintStyle {
+ let data = self.dep_kind_info(kind);
+ if data.is_anon {
+ return FingerprintStyle::Opaque;
+ }
+ data.fingerprint_style
+ }
+
+ #[inline(always)]
+ /// Return whether this kind always require evaluation.
+ fn is_eval_always(&self, kind: Self::DepKind) -> bool {
+ self.dep_kind_info(kind).is_eval_always
+ }
/// Try to force a dep node to execute and see if it's green.
- fn try_force_from_dep_node(&self, dep_node: DepNode<Self::DepKind>) -> bool;
+ fn try_force_from_dep_node(self, dep_node: DepNode<Self::DepKind>) -> bool {
+ debug!("try_force_from_dep_node({:?}) --- trying to force", dep_node);
+
+ let cb = self.dep_kind_info(dep_node.kind);
+ if let Some(f) = cb.force_from_dep_node {
+ f(self, dep_node);
+ true
+ } else {
+ false
+ }
+ }
/// Load data from the on-disk cache.
- fn try_load_from_on_disk_cache(&self, dep_node: DepNode<Self::DepKind>);
+ fn try_load_from_on_disk_cache(self, dep_node: DepNode<Self::DepKind>) {
+ let cb = self.dep_kind_info(dep_node.kind);
+ if let Some(f) = cb.try_load_from_on_disk_cache {
+ f(self, dep_node)
+ }
+ }
}
pub trait HasDepContext: Copy {
@@ -67,6 +94,8 @@ impl<T: DepContext> HasDepContext for T {
pub enum FingerprintStyle {
/// The fingerprint is actually a DefPathHash.
DefPathHash,
+ /// The fingerprint is actually a HirId.
+ HirId,
/// Query key was `()` or equivalent, so fingerprint is just zero.
Unit,
/// Some opaque hash.
@@ -77,7 +106,9 @@ impl FingerprintStyle {
#[inline]
pub fn reconstructible(self) -> bool {
match self {
- FingerprintStyle::DefPathHash | FingerprintStyle::Unit => true,
+ FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => {
+ true
+ }
FingerprintStyle::Opaque => false,
}
}
diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs
index 3fb06cbed..7a20eaceb 100644
--- a/compiler/rustc_query_system/src/error.rs
+++ b/compiler/rustc_query_system/src/error.rs
@@ -1,17 +1,15 @@
-use rustc_errors::AddSubdiagnostic;
-use rustc_span::Span;
+use rustc_macros::{Diagnostic, Subdiagnostic};
+use rustc_session::Limit;
+use rustc_span::{Span, Symbol};
+#[derive(Subdiagnostic)]
+#[note(query_system_cycle_stack_middle)]
pub struct CycleStack {
+ #[primary_span]
pub span: Span,
pub desc: String,
}
-impl AddSubdiagnostic for CycleStack {
- fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
- diag.span_note(self.span, &format!("...which requires {}...", self.desc));
- }
-}
-
#[derive(Copy, Clone)]
pub enum HandleCycleError {
Error,
@@ -19,39 +17,39 @@ pub enum HandleCycleError {
DelayBug,
}
-#[derive(SessionSubdiagnostic)]
+#[derive(Subdiagnostic)]
pub enum StackCount {
- #[note(query_system::cycle_stack_single)]
+ #[note(query_system_cycle_stack_single)]
Single,
- #[note(query_system::cycle_stack_multiple)]
+ #[note(query_system_cycle_stack_multiple)]
Multiple,
}
-#[derive(SessionSubdiagnostic)]
+#[derive(Subdiagnostic)]
pub enum Alias {
- #[note(query_system::cycle_recursive_ty_alias)]
- #[help(query_system::cycle_recursive_ty_alias_help1)]
- #[help(query_system::cycle_recursive_ty_alias_help2)]
+ #[note(query_system_cycle_recursive_ty_alias)]
+ #[help(query_system_cycle_recursive_ty_alias_help1)]
+ #[help(query_system_cycle_recursive_ty_alias_help2)]
Ty,
- #[note(query_system::cycle_recursive_trait_alias)]
+ #[note(query_system_cycle_recursive_trait_alias)]
Trait,
}
-#[derive(SessionSubdiagnostic)]
-#[note(query_system::cycle_usage)]
+#[derive(Subdiagnostic)]
+#[note(query_system_cycle_usage)]
pub struct CycleUsage {
#[primary_span]
pub span: Span,
pub usage: String,
}
-#[derive(SessionDiagnostic)]
-#[diag(query_system::cycle, code = "E0391")]
+#[derive(Diagnostic)]
+#[diag(query_system_cycle, code = "E0391")]
pub struct Cycle {
#[primary_span]
pub span: Span,
pub stack_bottom: String,
- #[subdiagnostic]
+ #[subdiagnostic(eager)]
pub cycle_stack: Vec<CycleStack>,
#[subdiagnostic]
pub stack_count: StackCount,
@@ -61,20 +59,35 @@ pub struct Cycle {
pub cycle_usage: Option<CycleUsage>,
}
-#[derive(SessionDiagnostic)]
-#[diag(query_system::reentrant)]
+#[derive(Diagnostic)]
+#[diag(query_system_reentrant)]
pub struct Reentrant;
-#[derive(SessionDiagnostic)]
-#[diag(query_system::increment_compilation)]
+#[derive(Diagnostic)]
+#[diag(query_system_increment_compilation)]
#[help]
-#[note(query_system::increment_compilation_note1)]
-#[note(query_system::increment_compilation_note2)]
+#[note(query_system_increment_compilation_note1)]
+#[note(query_system_increment_compilation_note2)]
pub struct IncrementCompilation {
pub run_cmd: String,
pub dep_node: String,
}
-#[derive(SessionDiagnostic)]
-#[diag(query_system::query_overflow)]
-pub struct QueryOverflow;
+#[derive(Diagnostic)]
+#[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(Subdiagnostic)]
+#[note(query_system_layout_of_depth)]
+pub struct LayoutOfDepth {
+ pub desc: String,
+ pub depth: usize,
+}
diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs
index a09b8ca30..148eabb38 100644
--- a/compiler/rustc_query_system/src/ich/hcx.rs
+++ b/compiler/rustc_query_system/src/ich/hcx.rs
@@ -12,7 +12,7 @@ use rustc_session::cstore::CrateStore;
use rustc_session::Session;
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::Symbol;
-use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
+use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData, DUMMY_SP};
/// This is the context state available during incr. comp. hashing. It contains
/// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e.,
@@ -41,7 +41,10 @@ pub struct StableHashingContext<'a> {
pub(super) enum BodyResolver<'tcx> {
Forbidden,
Ignore,
- Traverse { owner: LocalDefId, bodies: &'tcx SortedMap<hir::ItemLocalId, &'tcx hir::Body<'tcx>> },
+ Traverse {
+ owner: hir::OwnerId,
+ bodies: &'tcx SortedMap<hir::ItemLocalId, &'tcx hir::Body<'tcx>>,
+ },
}
impl<'a> StableHashingContext<'a> {
@@ -103,7 +106,7 @@ impl<'a> StableHashingContext<'a> {
#[inline]
pub fn with_hir_bodies(
&mut self,
- owner: LocalDefId,
+ owner: hir::OwnerId,
bodies: &SortedMap<hir::ItemLocalId, &hir::Body<'_>>,
f: impl FnOnce(&mut StableHashingContext<'_>),
) {
@@ -182,7 +185,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
#[inline]
fn def_span(&self, def_id: LocalDefId) -> Span {
- self.source_span[def_id]
+ *self.source_span.get(def_id).unwrap_or(&DUMMY_SP)
}
#[inline]
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index f92c3831f..f47760e9a 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -1,11 +1,10 @@
#![feature(assert_matches)]
#![feature(core_intrinsics)]
#![feature(hash_raw_entry)]
-#![cfg_attr(bootstrap, feature(let_else))]
#![feature(min_specialization)]
#![feature(extern_types)]
#![allow(rustc::potential_query_instability)]
-// #![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
@@ -23,4 +22,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/config.rs b/compiler/rustc_query_system/src/query/config.rs
index c4549cc9e..0a1cffa3b 100644
--- a/compiler/rustc_query_system/src/query/config.rs
+++ b/compiler/rustc_query_system/src/query/config.rs
@@ -49,8 +49,6 @@ impl<CTX: QueryContext, K, V> QueryVTable<CTX, K, V> {
pub trait QueryDescription<CTX: QueryContext>: QueryConfig {
type Cache: QueryCache<Key = Self::Key, Stored = Self::Stored, Value = Self::Value>;
- fn describe(tcx: CTX, key: Self::Key) -> String;
-
// Don't use this method to access query results, instead use the methods on TyCtxt
fn query_state<'a>(tcx: CTX) -> &'a QueryState<Self::Key>
where
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 45b4079fb..ed65393f5 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -3,9 +3,11 @@ use crate::query::plumbing::CycleError;
use crate::query::{QueryContext, QueryStackFrame};
use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, Level};
+use rustc_errors::{
+ Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, Level,
+};
use rustc_hir::def::DefKind;
-use rustc_session::{Session, SessionDiagnostic};
+use rustc_session::Session;
use rustc_span::Span;
use std::hash::Hash;
@@ -59,6 +61,7 @@ impl QueryJobId {
}
}
+#[derive(Clone)]
pub struct QueryJobInfo {
pub query: QueryStackFrame,
pub job: QueryJob,
@@ -116,10 +119,10 @@ impl QueryJob {
}
}
-#[cfg(not(parallel_compiler))]
impl QueryJobId {
#[cold]
#[inline(never)]
+ #[cfg(not(parallel_compiler))]
pub(super) fn find_cycle_in_stack(
&self,
query_map: QueryMap,
@@ -156,6 +159,24 @@ impl QueryJobId {
panic!("did not find a cycle")
}
+
+ #[cold]
+ #[inline(never)]
+ 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;
+
+ while let Some(id) = current_id {
+ let info = query_map.get(&id).unwrap();
+ if info.query.name == "layout_of" {
+ depth += 1;
+ last_layout = Some((info.clone(), depth));
+ }
+ current_id = info.job.parent;
+ }
+ last_layout
+ }
}
#[cfg(parallel_compiler)]
@@ -530,7 +551,7 @@ pub fn deadlock(query_map: QueryMap, registry: &rayon_core::Registry) {
#[cold]
pub(crate) fn report_cycle<'a>(
sess: &'a Session,
- CycleError { usage, cycle: stack }: CycleError,
+ CycleError { usage, cycle: stack }: &CycleError,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
assert!(!stack.is_empty());
@@ -548,10 +569,10 @@ pub(crate) fn report_cycle<'a>(
}
let mut cycle_usage = None;
- if let Some((span, query)) = usage {
+ if let Some((span, ref query)) = *usage {
cycle_usage = Some(crate::error::CycleUsage {
span: query.default_span(span),
- usage: query.description,
+ usage: query.description.to_string(),
});
}
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 0b07bb64b..118703fc0 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -14,10 +14,11 @@ 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;
+use rustc_span::def_id::DefId;
use rustc_span::Span;
use thin_vec::ThinVec;
@@ -29,7 +30,9 @@ pub struct QueryStackFrame {
pub name: &'static str,
pub description: String,
span: Option<Span>,
- def_kind: Option<DefKind>,
+ pub def_id: Option<DefId>,
+ pub def_kind: Option<DefKind>,
+ pub ty_adt_id: Option<DefId>,
/// This hash is used to deterministically pick
/// a query to remove cycles in the parallel compiler.
#[cfg(parallel_compiler)]
@@ -42,14 +45,18 @@ impl QueryStackFrame {
name: &'static str,
description: String,
span: Option<Span>,
+ def_id: Option<DefId>,
def_kind: Option<DefKind>,
+ ty_adt_id: Option<DefId>,
_hash: impl FnOnce() -> u64,
) -> Self {
Self {
name,
description,
span,
+ def_id,
def_kind,
+ ty_adt_id,
#[cfg(parallel_compiler)]
hash: _hash(),
}
@@ -123,7 +130,5 @@ pub trait QueryContext: HasDepContext {
compute: impl FnOnce() -> R,
) -> R;
- fn depth_limit_error(&self) {
- self.dep_context().sess().emit_fatal(crate::error::QueryOverflow);
- }
+ fn depth_limit_error(&self, job: QueryJobId);
}
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 8179a674a..15b89daa6 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -119,7 +119,7 @@ where
#[inline(never)]
fn mk_cycle<CTX, V, R>(
tcx: CTX,
- error: CycleError,
+ cycle_error: CycleError,
handler: HandleCycleError,
cache: &dyn crate::query::QueryStorage<Value = V, Stored = R>,
) -> R
@@ -128,13 +128,14 @@ where
V: std::fmt::Debug + Value<CTX::DepContext>,
R: Clone,
{
- let error = report_cycle(tcx.dep_context().sess(), error);
- let value = handle_cycle_error(*tcx.dep_context(), error, handler);
+ let error = report_cycle(tcx.dep_context().sess(), &cycle_error);
+ let value = handle_cycle_error(*tcx.dep_context(), &cycle_error, error, handler);
cache.store_nocache(value)
}
fn handle_cycle_error<CTX, V>(
tcx: CTX,
+ cycle_error: &CycleError,
mut error: DiagnosticBuilder<'_, ErrorGuaranteed>,
handler: HandleCycleError,
) -> V
@@ -146,7 +147,7 @@ where
match handler {
Error => {
error.emit();
- Value::from_cycle_error(tcx)
+ Value::from_cycle_error(tcx, &cycle_error.cycle)
}
Fatal => {
error.emit();
@@ -155,7 +156,7 @@ where
}
DelayBug => {
error.delay_as_bug();
- Value::from_cycle_error(tcx)
+ Value::from_cycle_error(tcx, &cycle_error.cycle)
}
}
}
diff --git a/compiler/rustc_query_system/src/values.rs b/compiler/rustc_query_system/src/values.rs
index aeef66f86..67fbf14e6 100644
--- a/compiler/rustc_query_system/src/values.rs
+++ b/compiler/rustc_query_system/src/values.rs
@@ -1,11 +1,12 @@
use crate::dep_graph::DepContext;
+use crate::query::QueryInfo;
pub trait Value<CTX: DepContext>: Sized {
- fn from_cycle_error(tcx: CTX) -> Self;
+ fn from_cycle_error(tcx: CTX, cycle: &[QueryInfo]) -> Self;
}
impl<CTX: DepContext, T> Value<CTX> for T {
- default fn from_cycle_error(tcx: CTX) -> T {
+ default fn from_cycle_error(tcx: CTX, _: &[QueryInfo]) -> T {
tcx.sess().abort_if_errors();
// Ideally we would use `bug!` here. But bug! is only defined in rustc_middle, and it's
// non-trivial to define it earlier.