fix some nits
This commit is contained in:
parent
b9746ce039
commit
261b727d76
@ -8,31 +8,20 @@ impl<T> DynSync for T {}
|
||||
} else {
|
||||
#[rustc_on_unimplemented(
|
||||
message = "`{Self}` doesn't implement `DynSend`. \
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Send`",
|
||||
label = "`{Self}` doesn't implement `DynSend`. \
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Send`"
|
||||
)]
|
||||
// Ensure data structures is `Send` if `sync::active()` is true.
|
||||
// `sync::active()` should be checked before using these data structures.
|
||||
// Note: Ensure that the data structure **will not break**
|
||||
// thread safety after being created.
|
||||
//
|
||||
// `sync::active()` should be checked when downcasting these data structures
|
||||
// to `Send` via `FromDyn`.
|
||||
// This is an auto trait for types which can be sent across threads if `sync::active()`
|
||||
// is true. These types can be wrapped in a `FromDyn` to get a `Send` type. Wrapping a
|
||||
// `Send` type in `IntoDyn` will create a `DynSend` type.
|
||||
pub unsafe auto trait DynSend {}
|
||||
|
||||
#[rustc_on_unimplemented(
|
||||
message = "`{Self}` doesn't implement `DynSync`. \
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Sync`",
|
||||
label = "`{Self}` doesn't implement `DynSync`. \
|
||||
Add it to `rustc_data_structures::marker` or use `IntoDyn` if it's already `Sync`"
|
||||
)]
|
||||
// Ensure data structures is `Sync` if `sync::active()` is true.
|
||||
// Note: Ensure that the data structure **will not break**
|
||||
// thread safety after being checked.
|
||||
//
|
||||
// `sync::active()` should be checked when downcasting these data structures
|
||||
// to `Send` via `FromDyn`.
|
||||
// This is an auto trait for types which can be shared across threads if `sync::active()`
|
||||
// is true. These types can be wrapped in a `FromDyn` to get a `Sync` type. Wrapping a
|
||||
// `Sync` type in `IntoDyn` will create a `DynSync` type.
|
||||
pub unsafe auto trait DynSync {}
|
||||
|
||||
// Same with `Sync` and `Send`.
|
||||
@ -110,8 +99,8 @@ macro_rules! impl_dyn_send {
|
||||
[thin_vec::ThinVec<T> where T: DynSend]
|
||||
[smallvec::SmallVec<A> where A: smallvec::Array + DynSend]
|
||||
|
||||
// We use `Send` here to omit some extra code, since they are only
|
||||
// used in `Send` situations now.
|
||||
// We use `Send` here, since they are only used in `Send` situations now.
|
||||
// In this case we don't need copy or change the codes in `crate::owning_ref`.
|
||||
[crate::owning_ref::OwningRef<O, T> where O: Send, T: ?Sized + Send]
|
||||
[crate::owning_ref::OwningRefMut<O, T> where O: Send, T: ?Sized + Send]
|
||||
);
|
||||
@ -196,8 +185,8 @@ macro_rules! impl_dyn_sync {
|
||||
[smallvec::SmallVec<A> where A: smallvec::Array + DynSync]
|
||||
[thin_vec::ThinVec<T> where T: DynSync]
|
||||
|
||||
// We use `Sync` here to omit some extra code, since they are only
|
||||
// used in `Sync` situations now.
|
||||
// We use `Sync` here, since they are only used in `Sync` situations now.
|
||||
// In this case we don't need copy or change the codes in `crate::owning_ref`.
|
||||
[crate::owning_ref::OwningRef<O, T> where O: Sync, T: ?Sized + Sync]
|
||||
[crate::owning_ref::OwningRefMut<O, T> where O: Sync, T: ?Sized + Sync]
|
||||
);
|
||||
@ -213,11 +202,11 @@ pub fn assert_dyn_send_sync_val<T: ?Sized + DynSync + DynSend>(_t: &T) {}
|
||||
pub struct FromDyn<T>(T);
|
||||
|
||||
impl<T> FromDyn<T> {
|
||||
// Check `sync::active()` when creating this structure
|
||||
// and downcasting to `Send`. So we can ensure it is
|
||||
// thread-safe.
|
||||
#[inline(always)]
|
||||
pub fn from(val: T) -> Self {
|
||||
// Check that `sync::active()` is true on creation so we can
|
||||
// implement `Send` and `Sync` for this structure when `T`
|
||||
// implements `DynSend` and `DynSync` respectively.
|
||||
#[cfg(parallel_compiler)]
|
||||
assert!(crate::sync::active());
|
||||
FromDyn(val)
|
||||
@ -229,11 +218,11 @@ pub fn into_inner(self) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
// `FromDyn` is `Send` if `T` is `DynSend`, since it check when created.
|
||||
// `FromDyn` is `Send` if `T` is `DynSend`, since it ensures that sync::active() is true.
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl<T: DynSend> Send for FromDyn<T> {}
|
||||
|
||||
// `FromDyn` is `Sync` if `T` is `DynSync`, since it check when created.
|
||||
// `FromDyn` is `Sync` if `T` is `DynSync`, since it ensures that sync::active() is true.
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl<T: DynSync> Sync for FromDyn<T> {}
|
||||
|
||||
|
@ -181,7 +181,7 @@ pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! parallel {
|
||||
($($blocks:block),*) => {{
|
||||
($($blocks:block),*) => {
|
||||
// We catch panics here ensuring that all the blocks execute.
|
||||
// This makes behavior consistent with the parallel compiler.
|
||||
let mut panic = None;
|
||||
@ -197,7 +197,7 @@ macro_rules! parallel {
|
||||
if let Some(panic) = panic {
|
||||
::std::panic::resume_unwind(panic);
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn par_for_each_in<T: IntoIterator>(t: T, mut for_each: impl FnMut(T::Item) + Sync + Send) {
|
||||
@ -368,6 +368,7 @@ pub fn join<A, B, RA: DynSend, RB: DynSend>(oper_a: A, oper_b: B) -> (RA, RB)
|
||||
}
|
||||
}
|
||||
|
||||
// This function only works when `mode::active()`.
|
||||
pub fn scope<'scope, OP, R>(op: OP) -> R
|
||||
where
|
||||
OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
|
||||
@ -381,24 +382,22 @@ pub fn scope<'scope, OP, R>(op: OP) -> R
|
||||
/// the current thread. Use that for the longest running block.
|
||||
#[macro_export]
|
||||
macro_rules! parallel {
|
||||
($fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => {
|
||||
parallel!($fblock [$block, $($c,)*] [$($rest),*])
|
||||
(impl $fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => {
|
||||
parallel!(impl $fblock [$block, $($c,)*] [$($rest),*])
|
||||
};
|
||||
($fblock:block [$($blocks:expr,)*] []) => {
|
||||
{
|
||||
::rustc_data_structures::sync::scope(|s| {
|
||||
$(let block = rustc_data_structures::sync::FromDyn::from(|| $blocks);
|
||||
s.spawn(move |_| block.into_inner()());)*
|
||||
(|| $fblock)();
|
||||
});
|
||||
}
|
||||
(impl $fblock:block [$($blocks:expr,)*] []) => {
|
||||
::rustc_data_structures::sync::scope(|s| {
|
||||
$(let block = rustc_data_structures::sync::FromDyn::from(|| $blocks);
|
||||
s.spawn(move |_| block.into_inner()());)*
|
||||
(|| $fblock)();
|
||||
});
|
||||
};
|
||||
($fblock:block, $($blocks:block),*) => {
|
||||
if rustc_data_structures::sync::active() {
|
||||
// Reverse the order of the later blocks since Rayon executes them in reverse order
|
||||
// when using a single thread. This ensures the execution order matches that
|
||||
// of a single threaded rustc
|
||||
parallel!($fblock [] [$($blocks),*]);
|
||||
parallel!(impl $fblock [] [$($blocks),*]);
|
||||
} else {
|
||||
// We catch panics here ensuring that all the blocks execute.
|
||||
// This makes behavior consistent with the parallel compiler.
|
||||
|
Loading…
Reference in New Issue
Block a user