core/sync/exclusive.rs
1//! Defines [`Exclusive`].
2
3use core::fmt;
4use core::future::Future;
5use core::marker::Tuple;
6use core::ops::{Coroutine, CoroutineState};
7use core::pin::Pin;
8use 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)]
83pub struct Exclusive<T: ?Sized> {
84 inner: T,
85}
86
87// See `Exclusive`'s docs for justification.
88#[unstable(feature = "exclusive_wrapper", issue = "98407")]
89unsafe impl<T: ?Sized> Sync for Exclusive<T> {}
90
91#[unstable(feature = "exclusive_wrapper", issue = "98407")]
92impl<T: ?Sized> fmt::Debug for Exclusive<T> {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
94 f.debug_struct("Exclusive").finish_non_exhaustive()
95 }
96}
97
98impl<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
117impl<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")]
166impl<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")]
174impl<F, Args> FnOnce<Args> for Exclusive<F>
175where
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")]
187impl<F, Args> FnMut<Args> for Exclusive<F>
188where
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")]
198impl<T> Future for Exclusive<T>
199where
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
211impl<R, G> Coroutine<R> for Exclusive<G>
212where
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}