@@ -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