-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
When we encode the incremental cache, we store information about every file that we've currently loaded:
rust/compiler/rustc_query_impl/src/on_disk_cache.rs
Lines 232 to 246 in 5531927
let files = tcx.sess.source_map().files(); | |
let mut file_to_file_index = | |
FxHashMap::with_capacity_and_hasher(files.len(), Default::default()); | |
let mut file_index_to_stable_id = | |
FxHashMap::with_capacity_and_hasher(files.len(), Default::default()); | |
for (index, file) in files.iter().enumerate() { | |
let index = SourceFileIndex(index as u32); | |
let file_ptr: *const SourceFile = &**file as *const _; | |
file_to_file_index.insert(file_ptr, index); | |
let source_file_id = EncodedSourceFileId::new(tcx, &file); | |
file_index_to_stable_id.insert(index, source_file_id); | |
} | |
(file_to_file_index, file_index_to_stable_id) |
When we decode a Span
, we assume that a file with the correct StableSourceFileId
has already been loaded:
rust/compiler/rustc_query_impl/src/on_disk_cache.rs
Lines 497 to 499 in 5531927
let stable_id = file_index_to_stable_id[&index].translate(tcx); | |
source_map | |
.source_file_by_stable_id(stable_id) |
For files in the current crate, this is true - we load all used files in the current crate during expansion (before the incremental cache is loaded), and any stale StableSourceFileId
s will be skipped due to the corresponding HIR depnodes being marked as red.
However, we may also end up ending a Span
of a file from a different crate. Most queries only cache results for local DefIds
, so this can usually open happen when macros are involved (e.g. a mir::Body
containing identifiers expanded from a foreign macro). Since macros executions occur before the incremental cache is set up, we should always have the necessary foreign SourceFile
s loaded before we try to decode any foreign Span
s from the incremental cache.
As a result, I don't think it's actually possible to hit this in practice. However, trying to cache a query result for a foreign DefId
can easily hit this - the foreign files associated with the spans we encode need not be loaded by any of the macros that we invoke. We should either make this a requirement of query caching (cache_on_disk_if { key.is_local() }
must always be used when the result can contain foreign Span
, or adjust the incremental cache to correctly load foreign files when decoding Span
s.