Skip to content

Commit 950aa3e

Browse files
authored
Rollup merge of #109213 - oli-obk:cstore, r=cjgillot
Eagerly intern and check CrateNum/StableCrateId collisions r? ``@cjgillot`` It seems better to check things ahead of time than checking them afterwards. The [previous version](#108390) was a bit nonsensical, so this addresses the feedback
2 parents 34fa6da + 460ecd2 commit 950aa3e

File tree

7 files changed

+33
-61
lines changed

7 files changed

+33
-61
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -5294,6 +5294,7 @@ name = "rustc_span"
52945294
version = "0.0.0"
52955295
dependencies = [
52965296
"cfg-if",
5297+
"indexmap",
52975298
"md-5",
52985299
"rustc_arena",
52995300
"rustc_data_structures",

compiler/rustc_metadata/src/creader.rs

+21-54
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob
66

77
use rustc_ast::expand::allocator::AllocatorKind;
88
use rustc_ast::{self as ast, *};
9-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
9+
use rustc_data_structures::fx::FxHashSet;
1010
use rustc_data_structures::svh::Svh;
1111
use rustc_data_structures::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, WriteGuard};
1212
use rustc_expand::base::SyntaxExtension;
13-
use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
13+
use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE};
1414
use rustc_hir::definitions::Definitions;
1515
use rustc_index::vec::IndexVec;
1616
use rustc_middle::ty::TyCtxt;
@@ -46,9 +46,8 @@ pub struct CStore {
4646
/// This crate has a `#[alloc_error_handler]` item.
4747
has_alloc_error_handler: bool,
4848

49-
/// This map is used to verify we get no hash conflicts between
50-
/// `StableCrateId` values.
51-
pub(crate) stable_crate_ids: FxHashMap<StableCrateId, CrateNum>,
49+
/// The interned [StableCrateId]s.
50+
pub(crate) stable_crate_ids: StableCrateIdMap,
5251

5352
/// Unused externs of the crate
5453
unused_externs: Vec<Symbol>,
@@ -144,9 +143,21 @@ impl CStore {
144143
})
145144
}
146145

147-
fn alloc_new_crate_num(&mut self) -> CrateNum {
148-
self.metas.push(None);
149-
CrateNum::new(self.metas.len() - 1)
146+
fn intern_stable_crate_id(&mut self, root: &CrateRoot) -> Result<CrateNum, CrateError> {
147+
assert_eq!(self.metas.len(), self.stable_crate_ids.len());
148+
let num = CrateNum::new(self.stable_crate_ids.len());
149+
if let Some(&existing) = self.stable_crate_ids.get(&root.stable_crate_id()) {
150+
let crate_name0 = root.name();
151+
if let Some(crate_name1) = self.metas[existing].as_ref().map(|data| data.name()) {
152+
Err(CrateError::StableCrateIdCollision(crate_name0, crate_name1))
153+
} else {
154+
Err(CrateError::SymbolConflictsCurrent(crate_name0))
155+
}
156+
} else {
157+
self.metas.push(None);
158+
self.stable_crate_ids.insert(root.stable_crate_id(), num);
159+
Ok(num)
160+
}
150161
}
151162

152163
pub fn has_crate_data(&self, cnum: CrateNum) -> bool {
@@ -247,7 +258,7 @@ impl CStore {
247258
}
248259

249260
pub fn new(sess: &Session) -> CStore {
250-
let mut stable_crate_ids = FxHashMap::default();
261+
let mut stable_crate_ids = StableCrateIdMap::default();
251262
stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE);
252263
CStore {
253264
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
@@ -342,42 +353,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
342353
None
343354
}
344355

345-
fn verify_no_symbol_conflicts(&self, root: &CrateRoot) -> Result<(), CrateError> {
346-
// Check for (potential) conflicts with the local crate
347-
if self.sess.local_stable_crate_id() == root.stable_crate_id() {
348-
return Err(CrateError::SymbolConflictsCurrent(root.name()));
349-
}
350-
351-
// Check for conflicts with any crate loaded so far
352-
for (_, other) in self.cstore.iter_crate_data() {
353-
// Same stable crate id but different SVH
354-
if other.stable_crate_id() == root.stable_crate_id() && other.hash() != root.hash() {
355-
bug!(
356-
"Previously returned E0523 here. \
357-
See https://github.com/rust-lang/rust/pull/100599 for additional discussion.\
358-
root.name() = {}.",
359-
root.name()
360-
);
361-
}
362-
}
363-
364-
Ok(())
365-
}
366-
367-
fn verify_no_stable_crate_id_hash_conflicts(
368-
&mut self,
369-
root: &CrateRoot,
370-
cnum: CrateNum,
371-
) -> Result<(), CrateError> {
372-
if let Some(existing) = self.cstore.stable_crate_ids.insert(root.stable_crate_id(), cnum) {
373-
let crate_name0 = root.name();
374-
let crate_name1 = self.cstore.get_crate_data(existing).name();
375-
return Err(CrateError::StableCrateIdCollision(crate_name0, crate_name1));
376-
}
377-
378-
Ok(())
379-
}
380-
381356
fn register_crate(
382357
&mut self,
383358
host_lib: Option<Library>,
@@ -396,7 +371,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
396371
self.sess.opts.externs.get(name.as_str()).map_or(false, |e| e.is_private_dep);
397372

398373
// Claim this crate number and cache it
399-
let cnum = self.cstore.alloc_new_crate_num();
374+
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
400375

401376
info!(
402377
"register crate `{}` (cnum = {}. private_dep = {})",
@@ -432,14 +407,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
432407
None
433408
};
434409

435-
// Perform some verification *after* resolve_crate_deps() above is
436-
// known to have been successful. It seems that - in error cases - the
437-
// cstore can be in a temporarily invalid state between cnum allocation
438-
// and dependency resolution and the verification code would produce
439-
// ICEs in that case (see #83045).
440-
self.verify_no_symbol_conflicts(&crate_root)?;
441-
self.verify_no_stable_crate_id_hash_conflicts(&crate_root, cnum)?;
442-
443410
let crate_metadata = CrateMetadata::new(
444411
self.sess,
445412
&self.cstore,

compiler/rustc_metadata/src/rmeta/decoder.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1709,10 +1709,6 @@ impl CrateMetadata {
17091709
self.root.name
17101710
}
17111711

1712-
pub(crate) fn stable_crate_id(&self) -> StableCrateId {
1713-
self.root.stable_crate_id
1714-
}
1715-
17161712
pub(crate) fn hash(&self) -> Svh {
17171713
self.root.hash
17181714
}

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,10 @@ impl CrateStore for CStore {
595595
}
596596

597597
fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum {
598-
self.stable_crate_ids[&stable_crate_id]
598+
*self
599+
.stable_crate_ids
600+
.get(&stable_crate_id)
601+
.unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
599602
}
600603

601604
/// Returns the `DefKey` for a given `DefId`. This indicates the

compiler/rustc_span/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ tracing = "0.1"
1818
sha1 = "0.10.0"
1919
sha2 = "0.10.1"
2020
md5 = { package = "md-5", version = "0.10.0" }
21+
indexmap = { version = "1.9.1" }

compiler/rustc_span/src/def_id.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
use crate::{HashStableContext, Symbol};
22
use rustc_data_structures::fingerprint::Fingerprint;
33
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
4+
use rustc_data_structures::unhash::Unhasher;
45
use rustc_data_structures::AtomicRef;
56
use rustc_index::vec::Idx;
67
use rustc_macros::HashStable_Generic;
78
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
89
use std::borrow::Borrow;
910
use std::fmt;
10-
use std::hash::{Hash, Hasher};
11+
use std::hash::{BuildHasherDefault, Hash, Hasher};
12+
13+
pub type StableCrateIdMap =
14+
indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>;
1115

1216
rustc_index::newtype_index! {
1317
#[custom_encodable]

tests/run-make-fulldeps/issue-83045/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ all:
2929
--crate-type=rlib \
3030
--edition=2018 \
3131
c.rs 2>&1 | tee $(TMPDIR)/output.txt || exit 0
32-
$(CGREP) E0463 < $(TMPDIR)/output.txt
32+
$(CGREP) E0519 < $(TMPDIR)/output.txt
3333
$(CGREP) -v "internal compiler error" < $(TMPDIR)/output.txt

0 commit comments

Comments
 (0)