1
1
//! Defines [`Exclusive`].
2
2
3
+ use core:: cmp:: Ordering ;
3
4
use core:: fmt;
4
5
use core:: future:: Future ;
5
- use core:: marker:: Tuple ;
6
+ use core:: hash:: { Hash , Hasher } ;
7
+ use core:: marker:: { StructuralPartialEq , Tuple } ;
6
8
use core:: ops:: { Coroutine , CoroutineState } ;
7
9
use core:: pin:: Pin ;
8
10
use core:: task:: { Context , Poll } ;
9
11
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`] .
13
15
///
14
16
/// 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`
16
18
/// to be `Sync`, it must be sound to _share_ across threads, that is, it must be sound
17
19
/// for `&Exclusive` to cross thread boundaries. By design, a `&Exclusive` has no API
18
20
/// whatsoever, making it useless, thus harmless, thus memory safe.
@@ -22,7 +24,9 @@ use core::task::{Context, Poll};
22
24
/// Rust compiler that something is `Sync` in practice.
23
25
///
24
26
/// ## 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
+ ///
26
30
/// ```compile_fail
27
31
/// use core::cell::Cell;
28
32
///
@@ -43,7 +47,8 @@ use core::task::{Context, Poll};
43
47
/// ```
44
48
///
45
49
/// `Exclusive` ensures the struct is `Sync` without stripping the future of its
46
- /// functionality.
50
+ /// functionality:
51
+ ///
47
52
/// ```
48
53
/// #![feature(exclusive_wrapper)]
49
54
/// use core::cell::Cell;
@@ -66,6 +71,7 @@ use core::task::{Context, Poll};
66
71
/// ```
67
72
///
68
73
/// ## Parallels with a mutex
74
+ ///
69
75
/// In some sense, `Exclusive` can be thought of as a _compile-time_ version of
70
76
/// a mutex, as the borrow-checker guarantees that only one `&mut` can exist
71
77
/// for any value. This is a parallel with the fact that
@@ -75,7 +81,7 @@ use core::task::{Context, Poll};
75
81
#[ doc( alias = "SyncWrapper" ) ]
76
82
#[ doc( alias = "SyncCell" ) ]
77
83
#[ 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
79
85
// use `&` access to the inner value, violating the `Sync` impl's safety
80
86
// requirements.
81
87
#[ derive( Default ) ]
@@ -221,3 +227,78 @@ where
221
227
G :: resume ( self . get_pin_mut ( ) , arg)
222
228
}
223
229
}
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