| 1 | //! Defines [`Exclusive`]. |
| 2 | |
| 3 | use core::fmt; |
| 4 | use core::future::Future; |
| 5 | use core::marker::Tuple; |
| 6 | use core::ops::{Coroutine, CoroutineState}; |
| 7 | use core::pin::Pin; |
| 8 | use core::task::{Context, Poll}; |
| 9 | |
| 10 | /// `Exclusive` provides only _mutable_ access, also referred to as _exclusive_ |
| 11 | /// access to the underlying value. It provides no _immutable_, or _shared_ |
| 12 | /// access to the underlying value. |
| 13 | /// |
| 14 | /// While this may seem not very useful, it allows `Exclusive` to _unconditionally_ |
| 15 | /// implement [`Sync`]. Indeed, the safety requirements of `Sync` state that for `Exclusive` |
| 16 | /// to be `Sync`, it must be sound to _share_ across threads, that is, it must be sound |
| 17 | /// for `&Exclusive` to cross thread boundaries. By design, a `&Exclusive` has no API |
| 18 | /// whatsoever, making it useless, thus harmless, thus memory safe. |
| 19 | /// |
| 20 | /// Certain constructs like [`Future`]s can only be used with _exclusive_ access, |
| 21 | /// and are often `Send` but not `Sync`, so `Exclusive` can be used as hint to the |
| 22 | /// Rust compiler that something is `Sync` in practice. |
| 23 | /// |
| 24 | /// ## Examples |
| 25 | /// Using a non-`Sync` future prevents the wrapping struct from being `Sync` |
| 26 | /// ```compile_fail |
| 27 | /// use core::cell::Cell; |
| 28 | /// |
| 29 | /// async fn other() {} |
| 30 | /// fn assert_sync<T: Sync>(t: T) {} |
| 31 | /// struct State<F> { |
| 32 | /// future: F |
| 33 | /// } |
| 34 | /// |
| 35 | /// assert_sync(State { |
| 36 | /// future: async { |
| 37 | /// let cell = Cell::new(1); |
| 38 | /// let cell_ref = &cell; |
| 39 | /// other().await; |
| 40 | /// let value = cell_ref.get(); |
| 41 | /// } |
| 42 | /// }); |
| 43 | /// ``` |
| 44 | /// |
| 45 | /// `Exclusive` ensures the struct is `Sync` without stripping the future of its |
| 46 | /// functionality. |
| 47 | /// ``` |
| 48 | /// #![feature(exclusive_wrapper)] |
| 49 | /// use core::cell::Cell; |
| 50 | /// use core::sync::Exclusive; |
| 51 | /// |
| 52 | /// async fn other() {} |
| 53 | /// fn assert_sync<T: Sync>(t: T) {} |
| 54 | /// struct State<F> { |
| 55 | /// future: Exclusive<F> |
| 56 | /// } |
| 57 | /// |
| 58 | /// assert_sync(State { |
| 59 | /// future: Exclusive::new(async { |
| 60 | /// let cell = Cell::new(1); |
| 61 | /// let cell_ref = &cell; |
| 62 | /// other().await; |
| 63 | /// let value = cell_ref.get(); |
| 64 | /// }) |
| 65 | /// }); |
| 66 | /// ``` |
| 67 | /// |
| 68 | /// ## Parallels with a mutex |
| 69 | /// In some sense, `Exclusive` can be thought of as a _compile-time_ version of |
| 70 | /// a mutex, as the borrow-checker guarantees that only one `&mut` can exist |
| 71 | /// for any value. This is a parallel with the fact that |
| 72 | /// `&` and `&mut` references together can be thought of as a _compile-time_ |
| 73 | /// version of a read-write lock. |
| 74 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 75 | #[doc (alias = "SyncWrapper" )] |
| 76 | #[doc (alias = "SyncCell" )] |
| 77 | #[doc (alias = "Unique" )] |
| 78 | // `Exclusive` can't have `PartialOrd`, `Clone`, etc. impls as they would |
| 79 | // use `&` access to the inner value, violating the `Sync` impl's safety |
| 80 | // requirements. |
| 81 | #[derive (Default)] |
| 82 | #[repr (transparent)] |
| 83 | pub struct Exclusive<T: ?Sized> { |
| 84 | inner: T, |
| 85 | } |
| 86 | |
| 87 | // See `Exclusive`'s docs for justification. |
| 88 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 89 | unsafe impl<T: ?Sized> Sync for Exclusive<T> {} |
| 90 | |
| 91 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 92 | impl<T: ?Sized> fmt::Debug for Exclusive<T> { |
| 93 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| 94 | f.debug_struct(name:"Exclusive" ).finish_non_exhaustive() |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | impl<T: Sized> Exclusive<T> { |
| 99 | /// Wrap a value in an `Exclusive` |
| 100 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 101 | #[must_use ] |
| 102 | #[inline ] |
| 103 | pub const fn new(t: T) -> Self { |
| 104 | Self { inner: t } |
| 105 | } |
| 106 | |
| 107 | /// Unwrap the value contained in the `Exclusive` |
| 108 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 109 | #[rustc_const_unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 110 | #[must_use ] |
| 111 | #[inline ] |
| 112 | pub const fn into_inner(self) -> T { |
| 113 | self.inner |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | impl<T: ?Sized> Exclusive<T> { |
| 118 | /// Gets exclusive access to the underlying value. |
| 119 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 120 | #[must_use ] |
| 121 | #[inline ] |
| 122 | pub const fn get_mut(&mut self) -> &mut T { |
| 123 | &mut self.inner |
| 124 | } |
| 125 | |
| 126 | /// Gets pinned exclusive access to the underlying value. |
| 127 | /// |
| 128 | /// `Exclusive` is considered to _structurally pin_ the underlying |
| 129 | /// value, which means _unpinned_ `Exclusive`s can produce _unpinned_ |
| 130 | /// access to the underlying value, but _pinned_ `Exclusive`s only |
| 131 | /// produce _pinned_ access to the underlying value. |
| 132 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 133 | #[must_use ] |
| 134 | #[inline ] |
| 135 | pub const fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> { |
| 136 | // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned |
| 137 | // `Pin::map_unchecked_mut` is not const, so we do this conversion manually |
| 138 | unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } |
| 139 | } |
| 140 | |
| 141 | /// Build a _mutable_ reference to an `Exclusive<T>` from |
| 142 | /// a _mutable_ reference to a `T`. This allows you to skip |
| 143 | /// building an `Exclusive` with [`Exclusive::new`]. |
| 144 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 145 | #[must_use ] |
| 146 | #[inline ] |
| 147 | pub const fn from_mut(r: &'_ mut T) -> &'_ mut Exclusive<T> { |
| 148 | // SAFETY: repr is ≥ C, so refs have the same layout; and `Exclusive` properties are `&mut`-agnostic |
| 149 | unsafe { &mut *(r as *mut T as *mut Exclusive<T>) } |
| 150 | } |
| 151 | |
| 152 | /// Build a _pinned mutable_ reference to an `Exclusive<T>` from |
| 153 | /// a _pinned mutable_ reference to a `T`. This allows you to skip |
| 154 | /// building an `Exclusive` with [`Exclusive::new`]. |
| 155 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 156 | #[must_use ] |
| 157 | #[inline ] |
| 158 | pub const fn from_pin_mut(r: Pin<&'_ mut T>) -> Pin<&'_ mut Exclusive<T>> { |
| 159 | // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned |
| 160 | // `Pin::map_unchecked_mut` is not const, so we do this conversion manually |
| 161 | unsafe { Pin::new_unchecked(Self::from_mut(r.get_unchecked_mut())) } |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 166 | impl<T> From<T> for Exclusive<T> { |
| 167 | #[inline ] |
| 168 | fn from(t: T) -> Self { |
| 169 | Self::new(t) |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 174 | impl<F, Args> FnOnce<Args> for Exclusive<F> |
| 175 | where |
| 176 | F: FnOnce<Args>, |
| 177 | Args: Tuple, |
| 178 | { |
| 179 | type Output = F::Output; |
| 180 | |
| 181 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output { |
| 182 | self.into_inner().call_once(args) |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 187 | impl<F, Args> FnMut<Args> for Exclusive<F> |
| 188 | where |
| 189 | F: FnMut<Args>, |
| 190 | Args: Tuple, |
| 191 | { |
| 192 | extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { |
| 193 | self.get_mut().call_mut(args) |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | #[unstable (feature = "exclusive_wrapper" , issue = "98407" )] |
| 198 | impl<T> Future for Exclusive<T> |
| 199 | where |
| 200 | T: Future + ?Sized, |
| 201 | { |
| 202 | type Output = T::Output; |
| 203 | |
| 204 | #[inline ] |
| 205 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 206 | self.get_pin_mut().poll(cx) |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | #[unstable (feature = "coroutine_trait" , issue = "43122" )] // also #98407 |
| 211 | impl<R, G> Coroutine<R> for Exclusive<G> |
| 212 | where |
| 213 | G: Coroutine<R> + ?Sized, |
| 214 | { |
| 215 | type Yield = G::Yield; |
| 216 | type Return = G::Return; |
| 217 | |
| 218 | #[inline ] |
| 219 | fn resume(self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> { |
| 220 | G::resume(self.get_pin_mut(), arg) |
| 221 | } |
| 222 | } |
| 223 | |