Auto merge of #119139 - michaelwoerister:cleanup-stable-source-file-id, r=cjgillot
Unify SourceFile::name_hash and StableSourceFileId This PR adapts the existing `StableSourceFileId` type so that it can be used instead of the `name_hash` field of `SourceFile`. This simplifies a few things that were kind of duplicated before. The PR should also fix issues https://github.com/rust-lang/rust/issues/112700 and https://github.com/rust-lang/rust/issues/115835, but I was not able to reproduce these issues in a regression test. As far as I can tell, the root cause of these issues is that the id of the originating crate is not hashed in the `HashStable` impl of `Span` and thus cache entries that should have been considered invalidated were loaded. After this PR, the `stable_id` field of `SourceFile` includes information about the originating crate, so that ICE should not occur anymore.
This commit is contained in:
commit
bf8716f1cd
10 changed files with 131 additions and 118 deletions
|
@ -1,6 +1,5 @@
|
|||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::stable_hasher::Hash64;
|
||||
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
|
@ -21,8 +20,10 @@ use rustc_session::Session;
|
|||
use rustc_span::hygiene::{
|
||||
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
|
||||
};
|
||||
use rustc_span::source_map::{SourceMap, StableSourceFileId};
|
||||
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{
|
||||
BytePos, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span, StableSourceFileId,
|
||||
};
|
||||
use rustc_span::{CachingSourceMapView, Symbol};
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::mem;
|
||||
|
@ -133,30 +134,18 @@ impl AbsoluteBytePos {
|
|||
}
|
||||
}
|
||||
|
||||
/// An `EncodedSourceFileId` is the same as a `StableSourceFileId` except that
|
||||
/// the source crate is represented as a [StableCrateId] instead of as a
|
||||
/// `CrateNum`. This way `EncodedSourceFileId` can be encoded and decoded
|
||||
/// without any additional context, i.e. with a simple `opaque::Decoder` (which
|
||||
/// is the only thing available when decoding the cache's [Footer].
|
||||
#[derive(Encodable, Decodable, Clone, Debug)]
|
||||
struct EncodedSourceFileId {
|
||||
file_name_hash: Hash64,
|
||||
stable_source_file_id: StableSourceFileId,
|
||||
stable_crate_id: StableCrateId,
|
||||
}
|
||||
|
||||
impl EncodedSourceFileId {
|
||||
#[inline]
|
||||
fn translate(&self, tcx: TyCtxt<'_>) -> StableSourceFileId {
|
||||
let cnum = tcx.stable_crate_id_to_crate_num(self.stable_crate_id);
|
||||
StableSourceFileId { file_name_hash: self.file_name_hash, cnum }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new(tcx: TyCtxt<'_>, file: &SourceFile) -> EncodedSourceFileId {
|
||||
let source_file_id = StableSourceFileId::new(file);
|
||||
EncodedSourceFileId {
|
||||
file_name_hash: source_file_id.file_name_hash,
|
||||
stable_crate_id: tcx.stable_crate_id(source_file_id.cnum),
|
||||
stable_source_file_id: file.stable_id,
|
||||
stable_crate_id: tcx.stable_crate_id(file.cnum),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -488,7 +477,9 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
|
|||
.borrow_mut()
|
||||
.entry(index)
|
||||
.or_insert_with(|| {
|
||||
let stable_id = file_index_to_stable_id[&index].translate(tcx);
|
||||
let source_file_id = &file_index_to_stable_id[&index];
|
||||
let source_file_cnum =
|
||||
tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
|
||||
|
||||
// If this `SourceFile` is from a foreign crate, then make sure
|
||||
// that we've imported all of the source files from that crate.
|
||||
|
@ -499,12 +490,14 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
|
|||
// that we will load the source files from that crate during macro
|
||||
// expansion, so we use `import_source_files` to ensure that the foreign
|
||||
// source files are actually imported before we call `source_file_by_stable_id`.
|
||||
if stable_id.cnum != LOCAL_CRATE {
|
||||
self.tcx.cstore_untracked().import_source_files(self.tcx.sess, stable_id.cnum);
|
||||
if source_file_cnum != LOCAL_CRATE {
|
||||
self.tcx
|
||||
.cstore_untracked()
|
||||
.import_source_files(self.tcx.sess, source_file_cnum);
|
||||
}
|
||||
|
||||
source_map
|
||||
.source_file_by_stable_id(stable_id)
|
||||
.source_file_by_stable_id(source_file_id.stable_source_file_id)
|
||||
.expect("failed to lookup `SourceFile` in new context")
|
||||
})
|
||||
.clone()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue