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

core/sync/
exclusive.rs

1//! Defines [`Exclusive`].
2
3use core::clone::TrivialClone;
4use core::cmp::Ordering;
5use core::fmt;
6use core::future::Future;
7use core::hash::{Hash, Hasher};
8use core::marker::{StructuralPartialEq, Tuple};
9use core::ops::{Coroutine, CoroutineState};
10use core::pin::Pin;
11use 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)]
90pub struct Exclusive<T: ?Sized> {
91    inner: T,
92}
93
94// See `Exclusive`'s docs for justification.
95#[unstable(feature = "exclusive_wrapper", issue = "98407")]
96unsafe impl<T: ?Sized> Sync for Exclusive<T> {}
97
98#[unstable(feature = "exclusive_wrapper", issue = "98407")]
99impl<T: ?Sized> fmt::Debug for Exclusive<T> {
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
101        f.debug_struct("Exclusive").finish_non_exhaustive()
102    }
103}
104
105impl<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
124impl<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")]
174impl<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")]
182impl<F, Args> FnOnce<Args> for Exclusive<F>
183where
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")]
195impl<F, Args> FnMut<Args> for Exclusive<F>
196where
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")]
206impl<F, Args> Fn<Args> for Exclusive<F>
207where
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")]
217impl<T> Future for Exclusive<T>
218where
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
230impl<R, G> Coroutine<R> for Exclusive<G>
231where
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")]
244impl<T> AsRef<T> for Exclusive<T>
245where
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")]
255impl<T> Clone for Exclusive<T>
256where
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")]
267unsafe impl<T> TrivialClone for Exclusive<T> where T: Sync + TrivialClone {}
268
269#[unstable(feature = "exclusive_wrapper", issue = "98407")]
270impl<T> Copy for Exclusive<T> where T: Sync + Copy {}
271
272#[unstable(feature = "exclusive_wrapper", issue = "98407")]
273impl<T, U> PartialEq<Exclusive<U>> for Exclusive<T>
274where
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")]
285impl<T> StructuralPartialEq for Exclusive<T> where T: Sync + StructuralPartialEq + ?Sized {}
286
287#[unstable(feature = "exclusive_wrapper", issue = "98407")]
288impl<T> Eq for Exclusive<T> where T: Sync + Eq + ?Sized {}
289
290#[unstable(feature = "exclusive_wrapper", issue = "98407")]
291impl<T> Hash for Exclusive<T>
292where
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")]
302impl<T, U> PartialOrd<Exclusive<U>> for Exclusive<T>
303where
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")]
314impl<T> Ord for Exclusive<T>
315where
316    T: Sync + Ord + ?Sized,
317{
318    #[inline]
319    fn cmp(&self, other: &Self) -> Ordering {
320        self.inner.cmp(&other.inner)
321    }
322}