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::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering};
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::hash_map::Entry;
|
||||
@ -677,18 +678,33 @@ impl DepGraph {
|
||||
} else {
|
||||
match dep_dep_node.kind {
|
||||
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
|
||||
// just fail to mark green.
|
||||
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
|
||||
/// incremental directory for later re-use. The primary example are
|
||||
/// the object files that we save for each partition at code
|
||||
|
13
src/test/incremental/issue-62649-path-collisions-happen.rs
Normal file
13
src/test/incremental/issue-62649-path-collisions-happen.rs
Normal file
@ -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…
x
Reference in New Issue
Block a user