| 1 | //! Defines [`Exclusive`]. |
| 2 | |
| 3 | use core::clone::TrivialClone; |
| 4 | use core::cmp::Ordering; |
| 5 | use core::fmt; |
| 6 | use core::future::Future; |
| 7 | use core::hash::{Hash, Hasher}; |
| 8 | use core::marker::{StructuralPartialEq, Tuple}; |
| 9 | use core::ops::{Coroutine, CoroutineState}; |
| 10 | use core::pin::Pin; |
| 11 | use core::task::{Context, Poll}; |
| 12 | |
| 13 | /// `Exclusive` provides _mutable_ access, also referred to as _exclusive_ |
| 14 | /// access to the underlying value. However, it only permits _immutable_, or _shared_ |
| 15 | /// access to the underlying value when that value is [`Sync`]. |
| 16 | /// |
| 17 | /// While this may seem not very useful, it allows `Exclusive` to _unconditionally_ |
| 18 | /// implement `Sync`. Indeed, the safety requirements of `Sync` state that for `Exclusive` |
| 19 | /// to be `Sync`, it must be sound to _share_ across threads, that is, it must be sound |
| 20 | /// for `&Exclusive` to cross thread boundaries. By design, a `&Exclusive<T>` for non-`Sync` T |
| 21 | /// has no API whatsoever, making it useless, thus harmless, thus memory safe. |
| 22 | /// |
| 23 | /// Certain constructs like [`Future`]s can only be used with _exclusive_ access, |
| 24 | /// and are often `Send` but not `Sync`, so `Exclusive` can be used as hint to the |
| 25 | /// Rust compiler that something is `Sync` in practice. |
| 26 | /// |
| 27 | /// ## Examples |
| 28 | /// |
| 29 | /// Using a non-`Sync` future prevents the wrapping struct from being `Sync`: |
| 30 | /// |
| 31 | /// ```compile_fail |
| 32 | /// use core::cell::Cell; |
| 33 | /// |
| 34 | /// async fn other() {} |
| 35 | /// fn assert_sync<T: Sync>(t: T) {} |
| 36 | /// struct State<F> { |
| 37 | /// future: F |
| 38 | /// } |
| 39 | /// |
| 40 | /// assert_sync(State { |
| 41 | /// future: async { |
| 42 | /// let cell = Cell::new(1); |
| 43 | /// let cell_ref = &cell; |
| 44 | /// other().await; |
| 45 | /// let value = cell_ref.get(); |
| 46 | /// } |
| 47 | /// }); |
| 48 | /// ``` |
| 49 | /// |
| 50 | /// `Exclusive` ensures the struct is `Sync` without stripping the future of its |
| 51 | /// functionality: |
| 52 | /// |
| 53 | /// ``` |
| 54 | /// #![feature(exclusive_wrapper)] |
| 55 | /// use core::cell::Cell; |
| 56 | /// use core::sync::Exclusive; |
| 57 | /// |
| 58 | /// async fn other() {} |
| 59 | /// fn assert_sync<T: Sync>(t: T) {} |
| 60 | /// struct State<F> { |
| 61 | /// future: Exclusive<F> |
| 62 | /// } |
| 63 | /// |
| 64 | /// assert_sync(State { |
| 65 | /// future: Exclusive::new(async { |
| 66 | /// let cell = Cell::new(1); |
| 67 | /// let cell_ref = &cell; |
| 68 | /// other().await; |
| 69 | /// let value = cell_ref.get(); |
| 70 | /// }) |
| 71 | /// }); |
| 72 | /// ``` |
| 73 | /// |
| 74 | /// ## Parallels with a mutex |
| 75 | /// |
| 76 | /// In some sense, `Exclusive` can be thought of as a _compile-time_ version of |
| 77 | /// a mutex, as the borrow-checker guarantees that only one `&mut` can exist |
| 78 | /// for any value. This is a parallel with the fact that |
| 79 | /// `&` and `&mut` references together can be thought of as a _compile-time_ |
| 80 | /// version of a read-write lock. |
| 81 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 82 | #[doc (alias = "SyncWrapper" )] |
| 83 | #[doc (alias = "SyncCell" )] |
| 84 | #[doc (alias = "Unique" )] |
| 85 | // `Exclusive` can't have derived `PartialOrd`, `Clone`, etc. impls as they would |
| 86 | // use `&` access to the inner value, violating the `Sync` impl's safety |
| 87 | // requirements. |
| 88 | #[derive (Default)] |
| 89 | #[repr (transparent)] |
| 90 | pub struct Exclusive<T: ?Sized> { |
| 91 | inner: T, |
| 92 | } |
| 93 | |
| 94 | // See `Exclusive`'s docs for justification. |
| 95 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 96 | unsafe impl<T: ?Sized> Sync for Exclusive<T> {} |
| 97 | |
| 98 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 99 | impl<T: ?Sized> fmt::Debug for Exclusive<T> { |
| 100 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 101 | f.debug_struct(name:"Exclusive" ).finish_non_exhaustive() |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | impl<T: Sized> Exclusive<T> { |
| 106 | /// Wrap a value in an `Exclusive` |
| 107 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 108 | #[must_use ] |
| 109 | #[inline ] |
| 110 | pub const fn new(t: T) -> Self { |
| 111 | Self { inner: t } |
| 112 | } |
| 113 | |
| 114 | /// Unwrap the value contained in the `Exclusive` |
| 115 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 116 | #[rustc_const_unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 117 | #[must_use ] |
| 118 | #[inline ] |
| 119 | pub const fn into_inner(self) -> T { |
| 120 | self.inner |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | impl<T: ?Sized> Exclusive<T> { |
| 125 | /// Gets exclusive access to the underlying value. |
| 126 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 127 | #[must_use ] |
| 128 | #[inline ] |
| 129 | pub const fn get_mut(&mut self) -> &mut T { |
| 130 | &mut self.inner |
| 131 | } |
| 132 | |
| 133 | /// Gets pinned exclusive access to the underlying value. |
| 134 | /// |
| 135 | /// `Exclusive` is considered to _structurally pin_ the underlying |
| 136 | /// value, which means _unpinned_ `Exclusive`s can produce _unpinned_ |
| 137 | /// access to the underlying value, but _pinned_ `Exclusive`s only |
| 138 | /// produce _pinned_ access to the underlying value. |
| 139 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 140 | #[must_use ] |
| 141 | #[inline ] |
| 142 | pub const fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> { |
| 143 | // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned |
| 144 | // `Pin::map_unchecked_mut` is not const, so we do this conversion manually |
| 145 | unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } |
| 146 | } |
| 147 | |
| 148 | /// Build a _mutable_ reference to an `Exclusive<T>` from |
| 149 | /// a _mutable_ reference to a `T`. This allows you to skip |
| 150 | /// building an `Exclusive` with [`Exclusive::new`]. |
| 151 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 152 | #[must_use ] |
| 153 | #[inline ] |
| 154 | pub const fn from_mut(r: &'_ mut T) -> &'_ mut Exclusive<T> { |
| 155 | // SAFETY: repr is ≥ C, so refs have the same layout; and `Exclusive` properties are `&mut`-agnostic |
| 156 | unsafe { &mut *(r as *mut T as *mut Exclusive<T>) } |
| 157 | } |
| 158 | |
| 159 | /// Build a _pinned mutable_ reference to an `Exclusive<T>` from |
| 160 | /// a _pinned mutable_ reference to a `T`. This allows you to skip |
| 161 | /// building an `Exclusive` with [`Exclusive::new`]. |
| 162 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 163 | #[must_use ] |
| 164 | #[inline ] |
| 165 | pub const fn from_pin_mut(r: Pin<&'_ mut T>) -> Pin<&'_ mut Exclusive<T>> { |
| 166 | // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned |
| 167 | // `Pin::map_unchecked_mut` is not const, so we do this conversion manually |
| 168 | unsafe { Pin::new_unchecked(Self::from_mut(r.get_unchecked_mut())) } |
| 169 | } |
| 170 | } |
| 171 | |
| 172 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 173 | #[rustc_const_unstable (feature = "const_convert" , issue = "143773" )] |
| 174 | impl<T> const From<T> for Exclusive<T> { |
| 175 | #[inline ] |
| 176 | fn from(t: T) -> Self { |
| 177 | Self::new(t) |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 182 | impl<F, Args> FnOnce<Args> for Exclusive<F> |
| 183 | where |
| 184 | F: FnOnce<Args>, |
| 185 | Args: Tuple, |
| 186 | { |
| 187 | type Output = F::Output; |
| 188 | |
| 189 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output { |
| 190 | self.into_inner().call_once(args) |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 195 | impl<F, Args> FnMut<Args> for Exclusive<F> |
| 196 | where |
| 197 | F: FnMut<Args>, |
| 198 | Args: Tuple, |
| 199 | { |
| 200 | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { |
| 201 | self.get_mut().call_mut(args) |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 206 | impl<F, Args> Fn<Args> for Exclusive<F> |
| 207 | where |
| 208 | F: Sync + Fn<Args>, |
| 209 | Args: Tuple, |
| 210 | { |
| 211 | extern "rust-call" fn call(&self, args: Args) -> Self::Output { |
| 212 | self.as_ref().call(args) |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 217 | impl<T> Future for Exclusive<T> |
| 218 | where |
| 219 | T: Future + ?Sized, |
| 220 | { |
| 221 | type Output = T::Output; |
| 222 | |
| 223 | #[inline ] |
| 224 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 225 | self.get_pin_mut().poll(cx) |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | #[unstable (feature = "coroutine_trait" , issue = "43122" )] // also #98407 |
| 230 | impl<R, G> Coroutine<R> for Exclusive<G> |
| 231 | where |
| 232 | G: Coroutine<R> + ?Sized, |
| 233 | { |
| 234 | type Yield = G::Yield; |
| 235 | type Return = G::Return; |
| 236 | |
| 237 | #[inline ] |
| 238 | fn resume(self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> { |
| 239 | G::resume(self.get_pin_mut(), arg) |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 244 | impl<T> AsRef<T> for Exclusive<T> |
| 245 | where |
| 246 | T: Sync + ?Sized, |
| 247 | { |
| 248 | #[inline ] |
| 249 | fn as_ref(&self) -> &T { |
| 250 | &self.inner |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 255 | impl<T> Clone for Exclusive<T> |
| 256 | where |
| 257 | T: Sync + Clone, |
| 258 | { |
| 259 | #[inline ] |
| 260 | fn clone(&self) -> Self { |
| 261 | Self { inner: self.inner.clone() } |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | #[doc (hidden)] |
| 266 | #[unstable (feature = "trivial_clone" , issue = "none" )] |
| 267 | unsafe impl<T> TrivialClone for Exclusive<T> where T: Sync + TrivialClone {} |
| 268 | |
| 269 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 270 | impl<T> Copy for Exclusive<T> where T: Sync + Copy {} |
| 271 | |
| 272 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 273 | impl<T, U> PartialEq<Exclusive<U>> for Exclusive<T> |
| 274 | where |
| 275 | T: Sync + PartialEq<U> + ?Sized, |
| 276 | U: Sync + ?Sized, |
| 277 | { |
| 278 | #[inline ] |
| 279 | fn eq(&self, other: &Exclusive<U>) -> bool { |
| 280 | self.inner == other.inner |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 285 | impl<T> StructuralPartialEq for Exclusive<T> where T: Sync + StructuralPartialEq + ?Sized {} |
| 286 | |
| 287 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 288 | impl<T> Eq for Exclusive<T> where T: Sync + Eq + ?Sized {} |
| 289 | |
| 290 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 291 | impl<T> Hash for Exclusive<T> |
| 292 | where |
| 293 | T: Sync + Hash + ?Sized, |
| 294 | { |
| 295 | #[inline ] |
| 296 | fn hash<H: Hasher>(&self, state: &mut H) { |
| 297 | Hash::hash(&self.inner, state) |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 302 | impl<T, U> PartialOrd<Exclusive<U>> for Exclusive<T> |
| 303 | where |
| 304 | T: Sync + PartialOrd<U> + ?Sized, |
| 305 | U: Sync + ?Sized, |
| 306 | { |
| 307 | #[inline ] |
| 308 | fn partial_cmp(&self, other: &Exclusive<U>) -> Option<Ordering> { |
| 309 | self.inner.partial_cmp(&other.inner) |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 314 | impl<T> Ord for Exclusive<T> |
| 315 | where |
| 316 | T: Sync + Ord + ?Sized, |
| 317 | { |
| 318 | #[inline ] |
| 319 | fn cmp(&self, other: &Self) -> Ordering { |
| 320 | self.inner.cmp(&other.inner) |
| 321 | } |
| 322 | } |
| 323 | |