1 //! This module contains a type that can make `Send + !Sync` types `Sync` by
2 //! disallowing all immutable access to the value.
3 //!
4 //! A similar primitive is provided in the `sync_wrapper` crate.
5 
6 use std::any::Any;
7 
8 pub(crate) struct SyncWrapper<T> {
9     value: T,
10 }
11 
12 // safety: The SyncWrapper being send allows you to send the inner value across
13 // thread boundaries.
14 unsafe impl<T: Send> Send for SyncWrapper<T> {}
15 
16 // safety: An immutable reference to a SyncWrapper is useless, so moving such an
17 // immutable reference across threads is safe.
18 unsafe impl<T> Sync for SyncWrapper<T> {}
19 
20 impl<T> SyncWrapper<T> {
new(value: T) -> Self21     pub(crate) fn new(value: T) -> Self {
22         Self { value }
23     }
24 
into_inner(self) -> T25     pub(crate) fn into_inner(self) -> T {
26         self.value
27     }
28 }
29 
30 impl SyncWrapper<Box<dyn Any + Send>> {
31     /// Attempt to downcast using `Any::downcast_ref()` to a type that is known to be `Sync`.
downcast_ref_sync<T: Any + Sync>(&self) -> Option<&T>32     pub(crate) fn downcast_ref_sync<T: Any + Sync>(&self) -> Option<&T> {
33         // SAFETY: if the downcast fails, the inner value is not touched,
34         // so no thread-safety violation can occur.
35         self.value.downcast_ref()
36     }
37 }
38