diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index ce99b01637b04..41a4896d89e52 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -805,8 +805,8 @@ fn resolver_for_lowering_raw<'tcx>( ); let krate = configure_and_expand(krate, &pre_configured_attrs, &mut resolver); - // Make sure we don't mutate the cstore from here on. - tcx.untracked().cstore.freeze(); + // Don't mutate the cstore or stable crate id map from here on. + tcx.untracked().freeze_cstore(); let ResolverOutputs { global_ctxt: untracked_resolutions, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index cbd6afd68473a..be856f01a9429 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -555,15 +555,15 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { ) }, crates: |tcx, ()| { - // The list of loaded crates is now frozen in query cache, - // so make sure cstore is not mutably accessed from here on. - tcx.untracked().cstore.freeze(); + // The loaded-crate list is now frozen in the query cache; stop + // mutating the cstore and stable crate id map from here on. + tcx.untracked().freeze_cstore(); tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum)) }, used_crates: |tcx, ()| { - // The list of loaded crates is now frozen in query cache, - // so make sure cstore is not mutably accessed from here on. - tcx.untracked().cstore.freeze(); + // The loaded-crate list is now frozen in the query cache; stop + // mutating the cstore and stable crate id map from here on. + tcx.untracked().freeze_cstore(); tcx.arena.alloc_from_iter( CStore::from_tcx(tcx) .iter_crate_data() diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 061471ccc97e0..fd60094e21558 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2091,8 +2091,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .time("resolve_postprocess", || self.cstore_mut().postprocess(self.tcx, krate)); }); - // Make sure we don't mutate the cstore from here on. - self.tcx.untracked().cstore.freeze(); + // Don't mutate the cstore or stable crate id map from here on. + self.tcx.untracked().freeze_cstore(); } fn traits_in_scope( diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 39fe9c80923ec..94237132bd393 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -224,3 +224,13 @@ pub struct Untracked { /// The interned [StableCrateId]s. pub stable_crate_ids: FreezeLock, } + +impl Untracked { + /// Freezes the cstore and, with it, the `StableCrateId` map, making reads of + /// both lock-free. The cstore is frozen first so any in-flight crate loading + /// (which writes the map) finishes before the map is frozen. + pub fn freeze_cstore(&self) { + self.cstore.freeze(); + self.stable_crate_ids.freeze(); + } +}