Auto merge of #107586 - SparrowLii:parallel-query, r=cjgillot
Introduce `DynSend` and `DynSync` auto trait for parallel compiler part of parallel-rustc #101566 This PR introduces `DynSend / DynSync` trait and `FromDyn / IntoDyn` structure in rustc_data_structure::marker. `FromDyn` can dynamically check data structures for thread safety when switching to parallel environments (such as calling `par_for_each_in`). This happens only when `-Z threads > 1` so it doesn't affect single-threaded mode's compile efficiency. r? `@cjgillot`
This commit is contained in:
commit
dd8ec9c88d
26 changed files with 557 additions and 110 deletions
|
@ -5,7 +5,7 @@ use rustc_ast as ast;
|
|||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
|
||||
use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
|
||||
|
@ -150,11 +150,6 @@ impl<'hir> Map<'hir> {
|
|||
self.tcx.hir_module_items(module).items()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn par_for_each_item(self, f: impl Fn(ItemId) + Sync + Send) {
|
||||
par_for_each_in(&self.tcx.hir_crate_items(()).items[..], |id| f(*id));
|
||||
}
|
||||
|
||||
pub fn def_key(self, def_id: LocalDefId) -> DefKey {
|
||||
// Accessing the DefKey is ok, since it is part of DefPathHash.
|
||||
self.tcx.definitions_untracked().def_key(def_id)
|
||||
|
@ -502,7 +497,7 @@ impl<'hir> Map<'hir> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn par_body_owners(self, f: impl Fn(LocalDefId) + Sync + Send) {
|
||||
pub fn par_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.tcx.hir_crate_items(()).body_owners[..], |&def_id| f(def_id));
|
||||
}
|
||||
|
||||
|
@ -640,7 +635,7 @@ impl<'hir> Map<'hir> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + Sync + Send) {
|
||||
pub fn par_for_each_module(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
|
||||
let crate_items = self.tcx.hir_crate_items(());
|
||||
par_for_each_in(&crate_items.submodules[..], |module| f(module.def_id))
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ pub mod place;
|
|||
use crate::ty::query::Providers;
|
||||
use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
|
||||
use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::*;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
|
@ -77,19 +77,19 @@ impl ModuleItems {
|
|||
self.owners().map(|id| id.def_id)
|
||||
}
|
||||
|
||||
pub fn par_items(&self, f: impl Fn(ItemId) + Send + Sync) {
|
||||
pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.items[..], |&id| f(id))
|
||||
}
|
||||
|
||||
pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + Send + Sync) {
|
||||
pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.trait_items[..], |&id| f(id))
|
||||
}
|
||||
|
||||
pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + Send + Sync) {
|
||||
pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.impl_items[..], |&id| f(id))
|
||||
}
|
||||
|
||||
pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + Send + Sync) {
|
||||
pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.foreign_items[..], |&id| f(id))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -496,7 +496,7 @@ pub struct GlobalCtxt<'tcx> {
|
|||
///
|
||||
/// FIXME(Centril): consider `dyn LintStoreMarker` once
|
||||
/// we can upcast to `Any` for some additional type safety.
|
||||
pub lint_store: Lrc<dyn Any + sync::Sync + sync::Send>,
|
||||
pub lint_store: Lrc<dyn Any + sync::DynSync + sync::DynSend>,
|
||||
|
||||
pub dep_graph: DepGraph,
|
||||
|
||||
|
@ -648,7 +648,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
/// reference to the context, to allow formatting values that need it.
|
||||
pub fn create_global_ctxt(
|
||||
s: &'tcx Session,
|
||||
lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
|
||||
lint_store: Lrc<dyn Any + sync::DynSend + sync::DynSync>,
|
||||
arena: &'tcx WorkerLocal<Arena<'tcx>>,
|
||||
hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
|
||||
untracked: Untracked,
|
||||
|
|
|
@ -94,8 +94,8 @@ where
|
|||
f(None)
|
||||
} else {
|
||||
// We could get an `ImplicitCtxt` pointer from another thread.
|
||||
// Ensure that `ImplicitCtxt` is `Sync`.
|
||||
sync::assert_sync::<ImplicitCtxt<'_, '_>>();
|
||||
// Ensure that `ImplicitCtxt` is `DynSync`.
|
||||
sync::assert_dyn_sync::<ImplicitCtxt<'_, '_>>();
|
||||
|
||||
unsafe { f(Some(downcast(context))) }
|
||||
}
|
||||
|
|
|
@ -199,6 +199,12 @@ impl<'a, T: Copy> IntoIterator for &'a List<T> {
|
|||
|
||||
unsafe impl<T: Sync> Sync for List<T> {}
|
||||
|
||||
// We need this since `List` uses extern type `OpaqueListContents`.
|
||||
#[cfg(parallel_compiler)]
|
||||
use rustc_data_structures::sync::DynSync;
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl<T: DynSync> DynSync for List<T> {}
|
||||
|
||||
// Safety:
|
||||
// Layouts of `Equivalent<T>` and `List<T>` are the same, modulo opaque tail,
|
||||
// thus aligns of `Equivalent<T>` and `List<T>` must be the same.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue