@@ -117,25 +117,42 @@ impl FileLoader for RealFileLoader {
117
117
}
118
118
}
119
119
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.
123
132
#[ 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
+ }
125
144
126
145
// FIXME: we need a more globally consistent approach to the problem solved by
127
146
// StableSourceFileId, perhaps built atop source_file.name_hash.
128
147
impl StableSourceFileId {
129
148
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 )
131
150
}
132
151
133
- fn new_from_name ( name : & FileName ) -> StableSourceFileId {
152
+ fn new_from_name ( name : & FileName , cnum : CrateNum ) -> StableSourceFileId {
134
153
let mut hasher = StableHasher :: new ( ) ;
135
-
136
154
name. hash ( & mut hasher) ;
137
-
138
- StableSourceFileId ( hasher. finish ( ) )
155
+ StableSourceFileId { file_name_hash : hasher. finish ( ) , cnum }
139
156
}
140
157
}
141
158
@@ -274,7 +291,7 @@ impl SourceMap {
274
291
// be empty, so the working directory will be used.
275
292
let ( filename, _) = self . path_mapping . map_filename_prefix ( & filename) ;
276
293
277
- let file_id = StableSourceFileId :: new_from_name ( & filename) ;
294
+ let file_id = StableSourceFileId :: new_from_name ( & filename, LOCAL_CRATE ) ;
278
295
279
296
let lrc_sf = match self . source_file_by_stable_id ( file_id) {
280
297
Some ( lrc_sf) => lrc_sf,
@@ -288,6 +305,10 @@ impl SourceMap {
288
305
self . hash_kind ,
289
306
) ) ;
290
307
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
+
291
312
let mut files = self . files . borrow_mut ( ) ;
292
313
293
314
files. source_files . push ( source_file. clone ( ) ) ;
0 commit comments