Thanks to visit codestin.com
Credit goes to doc.rust-lang.org

core/sync/
exclusive.rs

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