diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index e2193a97a0f4..997077ac4402 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -188,53 +188,6 @@ pub fn assert_dyn_send() {} pub fn assert_dyn_send_val(_t: &T) {} pub fn assert_dyn_send_sync_val(_t: &T) {} -#[derive(Copy, Clone)] -pub struct FromDyn(T); - -impl FromDyn { - #[inline(always)] - pub fn from(val: T) -> Self { - // Check that `sync::is_dyn_thread_safe()` is true on creation so we can - // implement `Send` and `Sync` for this structure when `T` - // implements `DynSend` and `DynSync` respectively. - assert!(crate::sync::is_dyn_thread_safe()); - FromDyn(val) - } - - #[inline(always)] - pub fn derive(&self, val: O) -> FromDyn { - // We already did the check for `sync::is_dyn_thread_safe()` when creating `Self` - FromDyn(val) - } - - #[inline(always)] - pub fn into_inner(self) -> T { - self.0 - } -} - -// `FromDyn` is `Send` if `T` is `DynSend`, since it ensures that sync::is_dyn_thread_safe() is true. -unsafe impl Send for FromDyn {} - -// `FromDyn` is `Sync` if `T` is `DynSync`, since it ensures that sync::is_dyn_thread_safe() is true. -unsafe impl Sync for FromDyn {} - -impl std::ops::Deref for FromDyn { - type Target = T; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::ops::DerefMut for FromDyn { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - // A wrapper to convert a struct that is already a `Send` or `Sync` into // an instance of `DynSend` and `DynSync`, since the compiler cannot infer // it automatically in some cases. (e.g. Box) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 327c28fd1389..7967b8c9a452 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -34,7 +34,7 @@ pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard}; #[doc(no_inline)] pub use self::lock::{Lock, LockGuard, Mode}; -pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; +pub use self::mode::{is_dyn_thread_safe, FromDyn, set_dyn_thread_safe_mode}; pub use self::parallel::{ broadcast, par_fns, par_for_each_in, par_join, par_map, parallel_guard, spawn, try_par_for_each_in, @@ -64,6 +64,8 @@ mod atomic { mod mode { use std::sync::atomic::{AtomicU8, Ordering}; + use crate::sync::{DynSend, DynSync}; + const UNINITIALIZED: u8 = 0; const DYN_NOT_THREAD_SAFE: u8 = 1; const DYN_THREAD_SAFE: u8 = 2; @@ -99,6 +101,53 @@ pub fn set_dyn_thread_safe_mode(mode: bool) { // Check that the mode was either uninitialized or was already set to the requested mode. assert!(previous.is_ok() || previous == Err(set)); } + + #[derive(Copy, Clone)] + pub struct FromDyn(T); + + impl FromDyn { + #[inline(always)] + pub fn from(val: T) -> Self { + // Check that `sync::is_dyn_thread_safe()` is true on creation so we can + // implement `Send` and `Sync` for this structure when `T` + // implements `DynSend` and `DynSync` respectively. + assert!(crate::sync::is_dyn_thread_safe()); + FromDyn(val) + } + + #[inline(always)] + pub fn derive(&self, val: O) -> FromDyn { + // We already did the check for `sync::is_dyn_thread_safe()` when creating `Self` + FromDyn(val) + } + + #[inline(always)] + pub fn into_inner(self) -> T { + self.0 + } + } + + // `FromDyn` is `Send` if `T` is `DynSend`, since it ensures that sync::is_dyn_thread_safe() is true. + unsafe impl Send for FromDyn {} + + // `FromDyn` is `Sync` if `T` is `DynSync`, since it ensures that sync::is_dyn_thread_safe() is true. + unsafe impl Sync for FromDyn {} + + impl std::ops::Deref for FromDyn { + type Target = T; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl std::ops::DerefMut for FromDyn { + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } } /// This makes locks panic if they are already held.