@@ -1990,9 +1990,106 @@ impl<T> const From<T> for UnsafeCell<T> {
19901990#[ unstable( feature = "coerce_unsized" , issue = "27732" ) ]
19911991impl < T : CoerceUnsized < U > , U > CoerceUnsized < UnsafeCell < U > > for UnsafeCell < T > { }
19921992
1993+ /// [`UnsafeCell`], but [`Sync`].
1994+ ///
1995+ /// This is just an `UnsafeCell`, except it implements `Sync`
1996+ /// if `T` implements `Sync`.
1997+ ///
1998+ /// `UnsafeCell` doesn't implement `Sync`, to prevent accidental mis-use.
1999+ /// You can use `SyncUnsafeCell` instead of `UnsafeCell` to allow it to be
2000+ /// shared between threads, if that's intentional.
2001+ /// Providing proper synchronization is still the task of the user,
2002+ /// making this type just as unsafe to use.
2003+ ///
2004+ /// See [`UnsafeCell`] for details.
2005+ #[ unstable( feature = "sync_unsafe_cell" , issue = "none" ) ]
2006+ #[ repr( transparent) ]
2007+ pub struct SyncUnsafeCell < T : ?Sized > {
2008+ value : UnsafeCell < T > ,
2009+ }
2010+
2011+ #[ unstable( feature = "sync_unsafe_cell" , issue = "none" ) ]
2012+ unsafe impl < T : ?Sized + Sync > Sync for SyncUnsafeCell < T > { }
2013+
2014+ #[ unstable( feature = "sync_unsafe_cell" , issue = "none" ) ]
2015+ impl < T > SyncUnsafeCell < T > {
2016+ /// Constructs a new instance of `SyncUnsafeCell` which will wrap the specified value.
2017+ #[ inline]
2018+ pub const fn new ( value : T ) -> Self {
2019+ Self { value : UnsafeCell { value } }
2020+ }
2021+
2022+ /// Unwraps the value.
2023+ #[ inline]
2024+ pub const fn into_inner ( self ) -> T {
2025+ self . value . into_inner ( )
2026+ }
2027+ }
2028+
2029+ #[ unstable( feature = "sync_unsafe_cell" , issue = "none" ) ]
2030+ impl < T : ?Sized > SyncUnsafeCell < T > {
2031+ /// Gets a mutable pointer to the wrapped value.
2032+ ///
2033+ /// This can be cast to a pointer of any kind.
2034+ /// Ensure that the access is unique (no active references, mutable or not)
2035+ /// when casting to `&mut T`, and ensure that there are no mutations
2036+ /// or mutable aliases going on when casting to `&T`
2037+ #[ inline]
2038+ pub const fn get ( & self ) -> * mut T {
2039+ self . value . get ( )
2040+ }
2041+
2042+ /// Returns a mutable reference to the underlying data.
2043+ ///
2044+ /// This call borrows the `SyncUnsafeCell` mutably (at compile-time) which
2045+ /// guarantees that we possess the only reference.
2046+ #[ inline]
2047+ pub const fn get_mut ( & mut self ) -> & mut T {
2048+ self . value . get_mut ( )
2049+ }
2050+
2051+ /// Gets a mutable pointer to the wrapped value.
2052+ ///
2053+ /// See [`UnsafeCell::get`] for details.
2054+ #[ inline]
2055+ pub const fn raw_get ( this : * const Self ) -> * mut T {
2056+ // We can just cast the pointer from `SyncUnsafeCell<T>` to `T` because
2057+ // of #[repr(transparent)] on both SyncUnsafeCell and UnsafeCell.
2058+ // See UnsafeCell::raw_get.
2059+ this as * const T as * mut T
2060+ }
2061+ }
2062+
2063+ #[ unstable( feature = "sync_unsafe_cell" , issue = "none" ) ]
2064+ impl < T : Default > Default for SyncUnsafeCell < T > {
2065+ /// Creates an `SyncUnsafeCell`, with the `Default` value for T.
2066+ fn default ( ) -> SyncUnsafeCell < T > {
2067+ SyncUnsafeCell :: new ( Default :: default ( ) )
2068+ }
2069+ }
2070+
2071+ #[ unstable( feature = "sync_unsafe_cell" , issue = "none" ) ]
2072+ #[ rustc_const_unstable( feature = "const_convert" , issue = "88674" ) ]
2073+ impl < T > const From < T > for SyncUnsafeCell < T > {
2074+ /// Creates a new `SyncUnsafeCell<T>` containing the given value.
2075+ fn from ( t : T ) -> SyncUnsafeCell < T > {
2076+ SyncUnsafeCell :: new ( t)
2077+ }
2078+ }
2079+
2080+ #[ unstable( feature = "coerce_unsized" , issue = "27732" ) ]
2081+ //#[unstable(feature = "sync_unsafe_cell", issue = "none")]
2082+ impl < T : CoerceUnsized < U > , U > CoerceUnsized < SyncUnsafeCell < U > > for SyncUnsafeCell < T > { }
2083+
19932084#[ allow( unused) ]
1994- fn assert_coerce_unsized ( a : UnsafeCell < & i32 > , b : Cell < & i32 > , c : RefCell < & i32 > ) {
2085+ fn assert_coerce_unsized (
2086+ a : UnsafeCell < & i32 > ,
2087+ b : SyncUnsafeCell < & i32 > ,
2088+ c : Cell < & i32 > ,
2089+ d : RefCell < & i32 > ,
2090+ ) {
19952091 let _: UnsafeCell < & dyn Send > = a;
1996- let _: Cell < & dyn Send > = b;
1997- let _: RefCell < & dyn Send > = c;
2092+ let _: SyncUnsafeCell < & dyn Send > = b;
2093+ let _: Cell < & dyn Send > = c;
2094+ let _: RefCell < & dyn Send > = d;
19982095}
0 commit comments