diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2020-01-29 09:34:43 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-29 09:34:43 +0900 |
| commit | cb3884adaa538a9d380ac64dd3c9bb6ce6738da6 (patch) | |
| tree | fa27a4039a8a185b3ce23bcd596a2660481707e5 /src | |
| parent | 3761dcd3467441f78939ccb3b341b03b6a7558d7 (diff) | |
| parent | 6f4b904aa999aded3b1ee317146387a8686715e3 (diff) | |
Rollup merge of #68289 - pnkfelix:issue-62649-dont-ice-on-path-collision-in-dep-graph, r=michaelwoerister
Don't ICE on path-collision in dep-graph
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/dep_graph/graph.rs | 39 | ||||
| -rw-r--r-- | src/test/incremental/issue-62649-path-collisions-happen.rs | 13 |
2 files changed, 43 insertions, 9 deletions
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 8d1efc7bc04..258723bb39d 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -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 diff --git a/src/test/incremental/issue-62649-path-collisions-happen.rs b/src/test/incremental/issue-62649-path-collisions-happen.rs new file mode 100644 index 00000000000..ee81be76baf --- /dev/null +++ b/src/test/incremental/issue-62649-path-collisions-happen.rs @@ -0,0 +1,13 @@ +// revisions: rpass1 rpass2 + +#[cfg(rpass1)] +pub trait Something { + fn foo(); +} + +#[cfg(rpass2)] +pub struct Something { + pub foo: u8, +} + +fn main() {} |
