- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
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 StableSourceFileIds 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 SourceFiles loaded before we try to decode any foreign Spans 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 Spans.