Skip to content

Commit 1b4168c

Browse files
committed
Auto merge of rust-lang#119139 - michaelwoerister:cleanup-stable-source-file-id, r=<try>
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 rust-lang#112700 and rust-lang#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.
2 parents 57ad505 + fa8ef25 commit 1b4168c

File tree

10 files changed

+131
-118
lines changed

10 files changed

+131
-118
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ fn hex_encode(data: &[u8]) -> String {
534534
}
535535

536536
pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
537-
let cache_key = Some((source_file.name_hash, source_file.src_hash));
537+
let cache_key = Some((source_file.stable_id, source_file.src_hash));
538538
return debug_context(cx)
539539
.created_files
540540
.borrow_mut()

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![doc = include_str!("doc.md")]
22

33
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
4+
use rustc_data_structures::unord::UnordMap;
45

56
use self::metadata::{file_metadata, type_di_node};
67
use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER};
@@ -20,8 +21,6 @@ use crate::value::Value;
2021
use rustc_codegen_ssa::debuginfo::type_names;
2122
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
2223
use rustc_codegen_ssa::traits::*;
23-
use rustc_data_structures::fx::FxHashMap;
24-
use rustc_data_structures::stable_hasher::Hash128;
2524
use rustc_data_structures::sync::Lrc;
2625
use rustc_hir::def_id::{DefId, DefIdMap};
2726
use rustc_index::IndexVec;
@@ -32,7 +31,9 @@ use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt};
3231
use rustc_session::config::{self, DebugInfo};
3332
use rustc_session::Session;
3433
use rustc_span::symbol::Symbol;
35-
use rustc_span::{BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span};
34+
use rustc_span::{
35+
BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId,
36+
};
3637
use rustc_target::abi::Size;
3738

3839
use libc::c_uint;
@@ -61,7 +62,7 @@ pub struct CodegenUnitDebugContext<'ll, 'tcx> {
6162
llcontext: &'ll llvm::Context,
6263
llmod: &'ll llvm::Module,
6364
builder: &'ll mut DIBuilder<'ll>,
64-
created_files: RefCell<FxHashMap<Option<(Hash128, SourceFileHash)>, &'ll DIFile>>,
65+
created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>,
6566

6667
type_map: metadata::TypeMap<'ll, 'tcx>,
6768
namespace_map: RefCell<DefIdMap<&'ll DIScope>>,

compiler/rustc_metadata/src/rmeta/decoder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
16761676
multibyte_chars,
16771677
non_narrow_chars,
16781678
normalized_pos,
1679-
name_hash,
1679+
stable_id,
16801680
..
16811681
} = source_file_to_import;
16821682

@@ -1721,7 +1721,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
17211721
let local_version = sess.source_map().new_imported_source_file(
17221722
name,
17231723
src_hash,
1724-
name_hash,
1724+
stable_id,
17251725
source_len.to_u32(),
17261726
self.cnum,
17271727
lines,

compiler/rustc_metadata/src/rmeta/encoder.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::Attribute;
55
use rustc_data_structures::fingerprint::Fingerprint;
66
use rustc_data_structures::fx::FxIndexSet;
77
use rustc_data_structures::memmap::{Mmap, MmapMut};
8-
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
8+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
99
use rustc_data_structures::sync::{join, par_for_each_in, Lrc};
1010
use rustc_data_structures::temp_dir::MaybeTempDir;
1111
use rustc_hir as hir;
@@ -26,11 +26,12 @@ use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
2626
use rustc_session::config::{CrateType, OptLevel};
2727
use rustc_span::hygiene::HygieneEncodeContext;
2828
use rustc_span::symbol::sym;
29-
use rustc_span::{ExternalSource, FileName, SourceFile, SpanData, SyntaxContext};
29+
use rustc_span::{
30+
ExternalSource, FileName, SourceFile, SpanData, StableSourceFileId, SyntaxContext,
31+
};
3032
use std::borrow::Borrow;
3133
use std::collections::hash_map::Entry;
3234
use std::fs::File;
33-
use std::hash::Hash;
3435
use std::io::{Read, Seek, Write};
3536
use std::path::{Path, PathBuf};
3637

@@ -495,6 +496,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
495496

496497
let mut adapted = TableBuilder::default();
497498

499+
let local_crate_stable_id = self.tcx.stable_crate_id(LOCAL_CRATE);
500+
498501
// Only serialize `SourceFile`s that were used during the encoding of a `Span`.
499502
//
500503
// The order in which we encode source files is important here: the on-disk format for
@@ -511,7 +514,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
511514
//
512515
// At this point we also erase the actual on-disk path and only keep
513516
// the remapped version -- as is necessary for reproducible builds.
514-
let mut source_file = match source_file.name {
517+
let mut adapted_source_file = (**source_file).clone();
518+
519+
match source_file.name {
515520
FileName::Real(ref original_file_name) => {
516521
let adapted_file_name = if self.tcx.sess.should_prefer_remapped_for_codegen() {
517522
source_map.path_mapping().to_embeddable_absolute_path(
@@ -525,22 +530,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
525530
)
526531
};
527532

528-
if adapted_file_name != *original_file_name {
529-
let mut adapted: SourceFile = (**source_file).clone();
530-
adapted.name = FileName::Real(adapted_file_name);
531-
adapted.name_hash = {
532-
let mut hasher: StableHasher = StableHasher::new();
533-
adapted.name.hash(&mut hasher);
534-
hasher.finish::<Hash128>()
535-
};
536-
Lrc::new(adapted)
537-
} else {
538-
// Nothing to adapt
539-
source_file.clone()
540-
}
533+
adapted_source_file.name = FileName::Real(adapted_file_name);
534+
}
535+
_ => {
536+
// expanded code, not from a file
541537
}
542-
// expanded code, not from a file
543-
_ => source_file.clone(),
544538
};
545539

546540
// We're serializing this `SourceFile` into our crate metadata,
@@ -550,12 +544,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
550544
// dependencies aren't loaded when we deserialize a proc-macro,
551545
// trying to remap the `CrateNum` would fail.
552546
if self.is_proc_macro {
553-
Lrc::make_mut(&mut source_file).cnum = LOCAL_CRATE;
547+
adapted_source_file.cnum = LOCAL_CRATE;
554548
}
555549

550+
// Update the `StableSourceFileId` to make sure it incorporates the
551+
// id of the current crate. This way it will be unique within the
552+
// crate graph during downstream compilation sessions.
553+
adapted_source_file.stable_id = StableSourceFileId::from_filename_for_export(
554+
&adapted_source_file.name,
555+
local_crate_stable_id,
556+
);
557+
556558
let on_disk_index: u32 =
557559
on_disk_index.try_into().expect("cannot export more than U32_MAX files");
558-
adapted.set_some(on_disk_index, self.lazy(source_file));
560+
adapted.set_some(on_disk_index, self.lazy(adapted_source_file));
559561
}
560562

561563
adapted.encode(&mut self.opaque)

compiler/rustc_middle/src/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
10981098
.files()
10991099
.iter()
11001100
.filter(|source_file| source_file.cnum == LOCAL_CRATE)
1101-
.map(|source_file| source_file.name_hash)
1101+
.map(|source_file| source_file.stable_id)
11021102
.collect();
11031103

11041104
source_file_names.sort_unstable();

compiler/rustc_middle/src/query/on_disk_cache.rs

+15-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
22
use rustc_data_structures::memmap::Mmap;
3-
use rustc_data_structures::stable_hasher::Hash64;
43
use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock};
54
use rustc_data_structures::unhash::UnhashMap;
65
use rustc_data_structures::unord::UnordSet;
@@ -21,8 +20,10 @@ use rustc_session::Session;
2120
use rustc_span::hygiene::{
2221
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
2322
};
24-
use rustc_span::source_map::{SourceMap, StableSourceFileId};
25-
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span};
23+
use rustc_span::source_map::SourceMap;
24+
use rustc_span::{
25+
BytePos, ExpnData, ExpnHash, Pos, RelativeBytePos, SourceFile, Span, StableSourceFileId,
26+
};
2627
use rustc_span::{CachingSourceMapView, Symbol};
2728
use std::collections::hash_map::Entry;
2829
use std::mem;
@@ -133,30 +134,18 @@ impl AbsoluteBytePos {
133134
}
134135
}
135136

136-
/// An `EncodedSourceFileId` is the same as a `StableSourceFileId` except that
137-
/// the source crate is represented as a [StableCrateId] instead of as a
138-
/// `CrateNum`. This way `EncodedSourceFileId` can be encoded and decoded
139-
/// without any additional context, i.e. with a simple `opaque::Decoder` (which
140-
/// is the only thing available when decoding the cache's [Footer].
141137
#[derive(Encodable, Decodable, Clone, Debug)]
142138
struct EncodedSourceFileId {
143-
file_name_hash: Hash64,
139+
stable_source_file_id: StableSourceFileId,
144140
stable_crate_id: StableCrateId,
145141
}
146142

147143
impl EncodedSourceFileId {
148-
#[inline]
149-
fn translate(&self, tcx: TyCtxt<'_>) -> StableSourceFileId {
150-
let cnum = tcx.stable_crate_id_to_crate_num(self.stable_crate_id);
151-
StableSourceFileId { file_name_hash: self.file_name_hash, cnum }
152-
}
153-
154144
#[inline]
155145
fn new(tcx: TyCtxt<'_>, file: &SourceFile) -> EncodedSourceFileId {
156-
let source_file_id = StableSourceFileId::new(file);
157146
EncodedSourceFileId {
158-
file_name_hash: source_file_id.file_name_hash,
159-
stable_crate_id: tcx.stable_crate_id(source_file_id.cnum),
147+
stable_source_file_id: file.stable_id,
148+
stable_crate_id: tcx.stable_crate_id(file.cnum),
160149
}
161150
}
162151
}
@@ -488,7 +477,9 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
488477
.borrow_mut()
489478
.entry(index)
490479
.or_insert_with(|| {
491-
let stable_id = file_index_to_stable_id[&index].translate(tcx);
480+
let source_file_id = &file_index_to_stable_id[&index];
481+
let source_file_cnum =
482+
tcx.stable_crate_id_to_crate_num(source_file_id.stable_crate_id);
492483

493484
// If this `SourceFile` is from a foreign crate, then make sure
494485
// that we've imported all of the source files from that crate.
@@ -499,12 +490,14 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
499490
// that we will load the source files from that crate during macro
500491
// expansion, so we use `import_source_files` to ensure that the foreign
501492
// source files are actually imported before we call `source_file_by_stable_id`.
502-
if stable_id.cnum != LOCAL_CRATE {
503-
self.tcx.cstore_untracked().import_source_files(self.tcx.sess, stable_id.cnum);
493+
if source_file_cnum != LOCAL_CRATE {
494+
self.tcx
495+
.cstore_untracked()
496+
.import_source_files(self.tcx.sess, source_file_cnum);
504497
}
505498

506499
source_map
507-
.source_file_by_stable_id(stable_id)
500+
.source_file_by_stable_id(source_file_id.stable_source_file_id)
508501
.expect("failed to lookup `SourceFile` in new context")
509502
})
510503
.clone()

compiler/rustc_query_system/src/ich/impls_syntax.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ impl<'ctx> rustc_ast::HashStableContext for StableHashingContext<'ctx> {
6060
impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
6161
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
6262
let SourceFile {
63-
name: _, // We hash the smaller name_hash instead of this
64-
name_hash,
63+
name: _, // We hash the smaller stable_id instead of this
64+
stable_id,
6565
cnum,
6666
// Do not hash the source as it is not encoded
6767
src: _,
@@ -75,7 +75,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
7575
ref normalized_pos,
7676
} = *self;
7777

78-
name_hash.hash_stable(hcx, hasher);
78+
stable_id.hash_stable(hcx, hasher);
7979

8080
src_hash.hash_stable(hcx, hasher);
8181

0 commit comments

Comments
 (0)