diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-03-03 06:17:06 +0100 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-03-07 01:56:59 +0100 |
| commit | 62089c335fbdbe2a04c432239dce9e6e8f9a5e8e (patch) | |
| tree | f87a18a8cd044b24e782e6a5eebb21885d1569fa /src/librustc_data_structures | |
| parent | e8af0f4c1f121263e55da29854208db0ae1fea54 (diff) | |
| download | rust-62089c335fbdbe2a04c432239dce9e6e8f9a5e8e.tar.gz rust-62089c335fbdbe2a04c432239dce9e6e8f9a5e8e.zip | |
Make metadata references Send + Sync
Diffstat (limited to 'src/librustc_data_structures')
| -rw-r--r-- | src/librustc_data_structures/owning_ref/mod.rs | 47 | ||||
| -rw-r--r-- | src/librustc_data_structures/sync.rs | 3 |
2 files changed, 43 insertions, 7 deletions
diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs index 23e0733748b..c466b8f8ad1 100644 --- a/src/librustc_data_structures/owning_ref/mod.rs +++ b/src/librustc_data_structures/owning_ref/mod.rs @@ -243,6 +243,7 @@ fn main() { ``` */ +use std::mem; pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress}; /// An owning reference. @@ -279,7 +280,7 @@ pub struct OwningRefMut<O, T: ?Sized> { pub trait Erased {} impl<T> Erased for T {} -/// Helper trait for erasing the concrete type of what an owner derferences to, +/// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box<T> -> Box<Erased>`. This would be unneeded with /// higher kinded types support in the language. pub unsafe trait IntoErased<'a> { @@ -289,10 +290,20 @@ pub unsafe trait IntoErased<'a> { fn into_erased(self) -> Self::Erased; } -/// Helper trait for erasing the concrete type of what an owner derferences to, +/// Helper trait for erasing the concrete type of what an owner dereferences to, +/// for example `Box<T> -> Box<Erased + Send>`. This would be unneeded with +/// higher kinded types support in the language. +pub unsafe trait IntoErasedSend<'a> { + /// Owner with the dereference type substituted to `Erased + Send`. + type Erased: Send; + /// Perform the type erasure. + fn into_erased_send(self) -> Self::Erased; +} + +/// Helper trait for erasing the concrete type of what an owner dereferences to, /// for example `Box<T> -> Box<Erased + Send + Sync>`. This would be unneeded with /// higher kinded types support in the language. -pub unsafe trait IntoErasedSendSync<'a>: Send + Sync { +pub unsafe trait IntoErasedSendSync<'a> { /// Owner with the dereference type substituted to `Erased + Send + Sync`. type Erased: Send + Sync; /// Perform the type erasure. @@ -472,6 +483,18 @@ impl<O, T: ?Sized> OwningRef<O, T> { } } + /// Erases the concrete base type of the owner with a trait object which implements `Send`. + /// + /// This allows mixing of owned references with different owner base types. + pub fn erase_send_owner<'a>(self) -> OwningRef<O::Erased, T> + where O: IntoErasedSend<'a>, + { + OwningRef { + reference: self.reference, + owner: self.owner.into_erased_send(), + } + } + /// Erases the concrete base type of the owner with a trait object which implements `Send` and `Sync`. /// /// This allows mixing of owned references with different owner base types. @@ -1161,13 +1184,25 @@ unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> { } } -unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Box<T> { - type Erased = Box<Erased + Send + Sync + 'a>; - fn into_erased_send_sync(self) -> Self::Erased { +unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box<T> { + type Erased = Box<Erased + Send + 'a>; + fn into_erased_send(self) -> Self::Erased { self } } +unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> { + type Erased = Box<Erased + Sync + Send + 'a>; + fn into_erased_send_sync(self) -> Self::Erased { + let result: Box<Erased + Send + 'a> = self; + // This is safe since Erased can always implement Sync + // Only the destructor is available and it takes &mut self + unsafe { + mem::transmute(result) + } + } +} + unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> { type Erased = Arc<Erased + Send + Sync + 'a>; fn into_erased_send_sync(self) -> Self::Erased { diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index b1ab4eaa069..69fc9ef785e 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -177,7 +177,7 @@ cfg_if! { macro_rules! rustc_erase_owner { ($v:expr) => {{ let v = $v; - ::rustc_data_structures::sync::assert_send_sync_val(&v); + ::rustc_data_structures::sync::assert_send_val(&v); v.erase_send_sync_owner() }} } @@ -262,6 +262,7 @@ cfg_if! { } pub fn assert_sync<T: ?Sized + Sync>() {} +pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {} pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {} #[macro_export] |
