@@ -1990,9 +1990,106 @@ impl<T> const From<T> for UnsafeCell<T> {
1990
1990
#[ unstable( feature = "coerce_unsized" , issue = "27732" ) ]
1991
1991
impl < T : CoerceUnsized < U > , U > CoerceUnsized < UnsafeCell < U > > for UnsafeCell < T > { }
1992
1992
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
+
1993
2084
#[ 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
+ ) {
1995
2091
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;
1998
2095
}
0 commit comments