Skip to content

OnDiskCache cannot decode Spans with foreign files #92014

Closed
@Aaron1011

Description

@Aaron1011

When we encode the incremental cache, we store information about every file that we've currently loaded:

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-incr-compArea: Incremental compilation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions