11//! Defines [`Exclusive`].
22
3+ use core:: cmp:: Ordering ;
34use core:: fmt;
45use core:: future:: Future ;
5- use core:: marker:: Tuple ;
6+ use core:: hash:: { Hash , Hasher } ;
7+ use core:: marker:: { StructuralPartialEq , Tuple } ;
68use core:: ops:: { Coroutine , CoroutineState } ;
79use core:: pin:: Pin ;
810use core:: task:: { Context , Poll } ;
911
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.
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`] .
1315///
1416/// 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`
17+ /// implement `Sync`. Indeed, the safety requirements of `Sync` state that for `Exclusive`
1618/// to be `Sync`, it must be sound to _share_ across threads, that is, it must be sound
1719/// for `&Exclusive` to cross thread boundaries. By design, a `&Exclusive` has no API
1820/// whatsoever, making it useless, thus harmless, thus memory safe.
@@ -22,7 +24,9 @@ use core::task::{Context, Poll};
2224/// Rust compiler that something is `Sync` in practice.
2325///
2426/// ## Examples
25- /// Using a non-`Sync` future prevents the wrapping struct from being `Sync`
27+ ///
28+ /// Using a non-`Sync` future prevents the wrapping struct from being `Sync`:
29+ ///
2630/// ```compile_fail
2731/// use core::cell::Cell;
2832///
@@ -43,7 +47,8 @@ use core::task::{Context, Poll};
4347/// ```
4448///
4549/// `Exclusive` ensures the struct is `Sync` without stripping the future of its
46- /// functionality.
50+ /// functionality:
51+ ///
4752/// ```
4853/// #![feature(exclusive_wrapper)]
4954/// use core::cell::Cell;
@@ -66,6 +71,7 @@ use core::task::{Context, Poll};
6671/// ```
6772///
6873/// ## Parallels with a mutex
74+ ///
6975/// In some sense, `Exclusive` can be thought of as a _compile-time_ version of
7076/// a mutex, as the borrow-checker guarantees that only one `&mut` can exist
7177/// for any value. This is a parallel with the fact that
@@ -75,7 +81,7 @@ use core::task::{Context, Poll};
7581#[ doc( alias = "SyncWrapper" ) ]
7682#[ doc( alias = "SyncCell" ) ]
7783#[ doc( alias = "Unique" ) ]
78- // `Exclusive` can't have `PartialOrd`, `Clone`, etc. impls as they would
84+ // `Exclusive` can't have derived `PartialOrd`, `Clone`, etc. impls as they would
7985// use `&` access to the inner value, violating the `Sync` impl's safety
8086// requirements.
8187#[ derive( Default ) ]
@@ -221,3 +227,78 @@ where
221227 G :: resume ( self . get_pin_mut ( ) , arg)
222228 }
223229}
230+
231+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
232+ impl < T > AsRef < T > for Exclusive < T >
233+ where
234+ T : Sync + ?Sized ,
235+ {
236+ #[ inline]
237+ fn as_ref ( & self ) -> & T {
238+ & self . inner
239+ }
240+ }
241+
242+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
243+ impl < T > Clone for Exclusive < T >
244+ where
245+ T : Sync + Clone ,
246+ {
247+ #[ inline]
248+ fn clone ( & self ) -> Self {
249+ Self { inner : self . inner . clone ( ) }
250+ }
251+ }
252+
253+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
254+ impl < T > Copy for Exclusive < T > where T : Sync + Copy { }
255+
256+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
257+ impl < T > PartialEq for Exclusive < T >
258+ where
259+ T : Sync + PartialEq + ?Sized ,
260+ {
261+ #[ inline]
262+ fn eq ( & self , other : & Self ) -> bool {
263+ self . inner == other. inner
264+ }
265+ }
266+
267+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
268+ impl < T > StructuralPartialEq for Exclusive < T > where T : Sync + StructuralPartialEq + ?Sized { }
269+
270+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
271+ impl < T > Eq for Exclusive < T > where T : Sync + Eq + ?Sized { }
272+
273+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
274+ impl < T > Hash for Exclusive < T >
275+ where
276+ T : Sync + Hash + ?Sized ,
277+ {
278+ #[ inline]
279+ fn hash < H : Hasher > ( & self , state : & mut H ) {
280+ Hash :: hash ( & self . inner , state)
281+ }
282+ }
283+
284+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
285+ impl < T > PartialOrd for Exclusive < T >
286+ where
287+ T : Sync + PartialOrd + ?Sized ,
288+ {
289+ #[ inline]
290+ fn partial_cmp ( & self , other : & Exclusive < T > ) -> Option < Ordering > {
291+ self . inner . partial_cmp ( & other. inner )
292+ }
293+ }
294+
295+ #[ unstable( feature = "exclusive_wrapper" , issue = "98407" ) ]
296+ impl < T > Ord for Exclusive < T >
297+ where
298+ T : Sync + Ord + ?Sized ,
299+ {
300+ #[ inline]
301+ fn cmp ( & self , other : & Self ) -> Ordering {
302+ self . inner . cmp ( & other. inner )
303+ }
304+ }
0 commit comments