mirror of https://github.com/rust-lang/rust.git
Collisions in the dep-graph due to path-reuse are rare but can occur.
So, instead of ICE'ing, just fail to mark green in such cases (for `DepKind::{Hir, HirBody, CrateMetadata}`). Fix #62649.
This commit is contained in:
parent
1d5f6d41e1
commit
6f4b904aa9
|
@ -6,6 +6,7 @@ use rustc_data_structures::sharded::{self, Sharded};
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
|
use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
|
||||||
use rustc_errors::Diagnostic;
|
use rustc_errors::Diagnostic;
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
@ -677,18 +678,33 @@ impl DepGraph {
|
||||||
} else {
|
} else {
|
||||||
match dep_dep_node.kind {
|
match dep_dep_node.kind {
|
||||||
DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => {
|
DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => {
|
||||||
if dep_dep_node.extract_def_id(tcx).is_none() {
|
if let Some(def_id) = dep_dep_node.extract_def_id(tcx) {
|
||||||
|
if def_id_corresponds_to_hir_dep_node(tcx, def_id) {
|
||||||
|
// The `DefPath` has corresponding node,
|
||||||
|
// and that node should have been marked
|
||||||
|
// either red or green in `data.colors`.
|
||||||
|
bug!(
|
||||||
|
"DepNode {:?} should have been \
|
||||||
|
pre-marked as red or green but wasn't.",
|
||||||
|
dep_dep_node
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// This `DefPath` does not have a
|
||||||
|
// corresponding `DepNode` (e.g. a
|
||||||
|
// struct field), and the ` DefPath`
|
||||||
|
// collided with the `DefPath` of a
|
||||||
|
// proper item that existed in the
|
||||||
|
// previous compilation session.
|
||||||
|
//
|
||||||
|
// Since the given `DefPath` does not
|
||||||
|
// denote the item that previously
|
||||||
|
// existed, we just fail to mark green.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// If the node does not exist anymore, we
|
// If the node does not exist anymore, we
|
||||||
// just fail to mark green.
|
// just fail to mark green.
|
||||||
return None;
|
return None;
|
||||||
} else {
|
|
||||||
// If the node does exist, it should have
|
|
||||||
// been pre-allocated.
|
|
||||||
bug!(
|
|
||||||
"DepNode {:?} should have been \
|
|
||||||
pre-allocated but wasn't.",
|
|
||||||
dep_dep_node
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -899,6 +915,11 @@ impl DepGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn def_id_corresponds_to_hir_dep_node(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
|
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||||
|
def_id.index == hir_id.owner
|
||||||
|
}
|
||||||
|
|
||||||
/// A "work product" is an intermediate result that we save into the
|
/// A "work product" is an intermediate result that we save into the
|
||||||
/// incremental directory for later re-use. The primary example are
|
/// incremental directory for later re-use. The primary example are
|
||||||
/// the object files that we save for each partition at code
|
/// the object files that we save for each partition at code
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// revisions: rpass1 rpass2
|
||||||
|
|
||||||
|
#[cfg(rpass1)]
|
||||||
|
pub trait Something {
|
||||||
|
fn foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(rpass2)]
|
||||||
|
pub struct Something {
|
||||||
|
pub foo: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue