@@ -96,11 +96,26 @@ pub struct ConstPtr<T: ?Sized> {
96
96
/// [here]: #correct-usage
97
97
#[ derive( Debug ) ]
98
98
pub struct MutPtr < T : ?Sized > {
99
- /// Drop guard representing the lifetime of the `ConstPtr `'s access.
99
+ /// Drop guard representing the lifetime of the `MutPtr `'s access.
100
100
_guard : rt:: cell:: Writing ,
101
101
ptr : * mut T ,
102
102
}
103
103
104
+ /// A checked mutable reference to an [`UnsafeCell`].
105
+ ///
106
+ /// This type is essentially a [`&mut T`], but with the added ability to
107
+ /// participate in Loom's [`UnsafeCell`] access tracking. While a `MutRef` to a
108
+ /// given [`UnsafeCell`] exists, Loom will track that the [`UnsafeCell`] is
109
+ /// being accessed mutably.
110
+ ///
111
+ /// [`MutRef`]s are produced by [`UnsafeCell::as_mut`].
112
+ #[ derive( Debug ) ]
113
+ pub struct MutRef < ' a , T : ?Sized > {
114
+ /// Drop guard representing the lifetime of the `MutRef`'s access.
115
+ _guard : rt:: cell:: Writing ,
116
+ ptr : & ' a mut T ,
117
+ }
118
+
104
119
impl < T > UnsafeCell < T > {
105
120
/// Constructs a new instance of `UnsafeCell` which will wrap the specified value.
106
121
#[ track_caller]
@@ -200,6 +215,21 @@ impl<T: ?Sized> UnsafeCell<T> {
200
215
ptr : self . data . get ( ) ,
201
216
}
202
217
}
218
+
219
+ /// Get a mutable reference to the wrapped value.
220
+ ///
221
+ /// This function returns a [`MutRef`] guard, which is analogous to a
222
+ /// `&mut T`, but tracked by Loom. As long as the returned `MutRef`
223
+ /// exists, Loom will consider the cell to be accessed mutably.
224
+ ///
225
+ /// This is analogous to [`core::cell::UnsafeCell::get_mut`].
226
+ #[ track_caller]
227
+ pub fn as_mut ( & mut self ) -> MutRef < ' _ , T > {
228
+ MutRef {
229
+ _guard : self . state . start_write ( location ! ( ) ) ,
230
+ ptr : self . data . get_mut ( ) ,
231
+ }
232
+ }
203
233
}
204
234
205
235
impl < T : Default > Default for UnsafeCell < T > {
@@ -382,6 +412,20 @@ impl<T: ?Sized> ConstPtr<T> {
382
412
}
383
413
}
384
414
415
+ impl < T : ?Sized > core:: ops:: Deref for MutRef < ' _ , T > {
416
+ type Target = T ;
417
+
418
+ fn deref ( & self ) -> & Self :: Target {
419
+ self . ptr
420
+ }
421
+ }
422
+
423
+ impl < T : ?Sized > core:: ops:: DerefMut for MutRef < ' _ , T > {
424
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
425
+ self . ptr
426
+ }
427
+ }
428
+
385
429
impl < T : ?Sized > MutPtr < T > {
386
430
/// Dereference the raw pointer.
387
431
///
0 commit comments