|
1 | | -use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; |
| 1 | +use crate::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex}; |
2 | 2 | use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; |
3 | 3 | use crate::mir::{self, interpret}; |
4 | 4 | use crate::ty::codec::{OpaqueEncoder, RefDecodable, TyDecoder, TyEncoder}; |
@@ -264,6 +264,13 @@ impl<'sess> OnDiskCache<'sess> { |
264 | 264 | (file_to_file_index, file_index_to_stable_id) |
265 | 265 | }; |
266 | 266 |
|
| 267 | + // Register any dep nodes that we reused from the previous session, |
| 268 | + // but didn't `DepNode::construct` in this session. This ensures |
| 269 | + // that their `DefPathHash` to `RawDefId` mappings are registered |
| 270 | + // in 'latest_foreign_def_path_hashes' if necessary, since that |
| 271 | + // normally happens in `DepNode::construct`. |
| 272 | + tcx.dep_graph.register_reused_dep_nodes(tcx); |
| 273 | + |
267 | 274 | // Load everything into memory so we can write it out to the on-disk |
268 | 275 | // cache. The vast majority of cacheable query results should already |
269 | 276 | // be in memory, so this should be a cheap operation. |
@@ -467,22 +474,33 @@ impl<'sess> OnDiskCache<'sess> { |
467 | 474 | .insert(hash, RawDefId { krate: def_id.krate.as_u32(), index: def_id.index.as_u32() }); |
468 | 475 | } |
469 | 476 |
|
470 | | - /// If the given `hash` still exists in the current compilation, |
471 | | - /// calls `store_foreign_def_id` with its current `DefId`. |
| 477 | + /// If the given `dep_node`'s hash still exists in the current compilation, |
| 478 | + /// and its current `DefId` is foreign, calls `store_foreign_def_id` with it. |
472 | 479 | /// |
473 | 480 | /// Normally, `store_foreign_def_id_hash` can be called directly by |
474 | 481 | /// the dependency graph when we construct a `DepNode`. However, |
475 | 482 | /// when we re-use a deserialized `DepNode` from the previous compilation |
476 | 483 | /// session, we only have the `DefPathHash` available. This method is used |
477 | 484 | /// to that any `DepNode` that we re-use has a `DefPathHash` -> `RawId` written |
478 | 485 | /// out for usage in the next compilation session. |
479 | | - pub fn register_reused_dep_path_hash(&self, tcx: TyCtxt<'tcx>, hash: DefPathHash) { |
480 | | - // We can't simply copy the `RawDefId` from `foreign_def_path_hashes` to |
481 | | - // `latest_foreign_def_path_hashes`, since the `RawDefId` might have |
482 | | - // changed in the current compilation session (e.g. we've added/removed crates, |
483 | | - // or added/removed definitions before/after the target definition). |
484 | | - if let Some(def_id) = self.def_path_hash_to_def_id(tcx, hash) { |
485 | | - self.store_foreign_def_id_hash(def_id, hash); |
| 486 | + pub fn register_reused_dep_node(&self, tcx: TyCtxt<'tcx>, dep_node: &DepNode) { |
| 487 | + // For reused dep nodes, we only need to store the mapping if the node |
| 488 | + // is one whose query key we can reconstruct from the hash. We use the |
| 489 | + // mapping to aid that reconstruction in the next session. While we also |
| 490 | + // use it to decode `DefId`s we encoded in the cache as `DefPathHashes`, |
| 491 | + // they're already registered during `DefId` encoding. |
| 492 | + if dep_node.kind.can_reconstruct_query_key() { |
| 493 | + let hash = DefPathHash(dep_node.hash.into()); |
| 494 | + |
| 495 | + // We can't simply copy the `RawDefId` from `foreign_def_path_hashes` to |
| 496 | + // `latest_foreign_def_path_hashes`, since the `RawDefId` might have |
| 497 | + // changed in the current compilation session (e.g. we've added/removed crates, |
| 498 | + // or added/removed definitions before/after the target definition). |
| 499 | + if let Some(def_id) = self.def_path_hash_to_def_id(tcx, hash) { |
| 500 | + if !def_id.is_local() { |
| 501 | + self.store_foreign_def_id_hash(def_id, hash); |
| 502 | + } |
| 503 | + } |
486 | 504 | } |
487 | 505 | } |
488 | 506 |
|
|
0 commit comments