Skip to content

Commit 68c3b0e

Browse files
Disambiguate between SourceFiles from different crates even if they have the same path.
1 parent 99e5a3f commit 68c3b0e

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

compiler/rustc_span/src/source_map.rs

+31-10
Original file line numberDiff line numberDiff line change
@@ -117,25 +117,42 @@ impl FileLoader for RealFileLoader {
117117
}
118118
}
119119

120-
// This is a `SourceFile` identifier that is used to correlate `SourceFile`s between
121-
// subsequent compilation sessions (which is something we need to do during
122-
// incremental compilation).
120+
/// This is a [SourceFile] identifier that is used to correlate source files between
121+
/// subsequent compilation sessions (which is something we need to do during
122+
/// incremental compilation).
123+
///
124+
/// The [StableSourceFileId] also contains the CrateNum of the crate the source
125+
/// file was originally parsed for. This way we get two separate entries in
126+
/// the [SourceMap] if the same file is part of both the local and an upstream
127+
/// crate. Trying to only have one entry for both cases is problematic because
128+
/// at the point where we discover that there's a local use of the file in
129+
/// addition to the upstream one, we might already have made decisions based on
130+
/// the assumption that it's an upstream file. Treating the two files as
131+
/// different has no real downsides.
123132
#[derive(Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Debug)]
124-
pub struct StableSourceFileId(u128);
133+
pub struct StableSourceFileId {
134+
// A hash of the source file's FileName. This is hash so that it's size
135+
// is more predictable than if we included the actual FileName value.
136+
file_name_hash: u64,
137+
138+
// The CrateNum of the crate this source file was originally parsed for.
139+
// We cannot include this information in the hash because at the time
140+
// of hashing we don't have the context to map from the CrateNum's numeric
141+
// value to a StableCrateId.
142+
cnum: CrateNum,
143+
}
125144

126145
// FIXME: we need a more globally consistent approach to the problem solved by
127146
// StableSourceFileId, perhaps built atop source_file.name_hash.
128147
impl StableSourceFileId {
129148
pub fn new(source_file: &SourceFile) -> StableSourceFileId {
130-
StableSourceFileId::new_from_name(&source_file.name)
149+
StableSourceFileId::new_from_name(&source_file.name, source_file.cnum)
131150
}
132151

133-
fn new_from_name(name: &FileName) -> StableSourceFileId {
152+
fn new_from_name(name: &FileName, cnum: CrateNum) -> StableSourceFileId {
134153
let mut hasher = StableHasher::new();
135-
136154
name.hash(&mut hasher);
137-
138-
StableSourceFileId(hasher.finish())
155+
StableSourceFileId { file_name_hash: hasher.finish(), cnum }
139156
}
140157
}
141158

@@ -274,7 +291,7 @@ impl SourceMap {
274291
// be empty, so the working directory will be used.
275292
let (filename, _) = self.path_mapping.map_filename_prefix(&filename);
276293

277-
let file_id = StableSourceFileId::new_from_name(&filename);
294+
let file_id = StableSourceFileId::new_from_name(&filename, LOCAL_CRATE);
278295

279296
let lrc_sf = match self.source_file_by_stable_id(file_id) {
280297
Some(lrc_sf) => lrc_sf,
@@ -288,6 +305,10 @@ impl SourceMap {
288305
self.hash_kind,
289306
));
290307

308+
// Let's make sure the file_id we generated above actually matches
309+
// the ID we generate for the SourceFile we just created.
310+
debug_assert_eq!(StableSourceFileId::new(&source_file), file_id);
311+
291312
let mut files = self.files.borrow_mut();
292313

293314
files.source_files.push(source_file.clone());

0 commit comments

Comments
 (0)