|
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