@@ -48,7 +48,9 @@ use core::cell::UnsafeCell;
48
48
use core:: cmp;
49
49
use core:: fmt;
50
50
use core:: fmt:: { Debug , Display } ;
51
+ use core:: marker:: PhantomData ;
51
52
use core:: ops:: { Deref , DerefMut } ;
53
+ use core:: ptr:: NonNull ;
52
54
use core:: sync:: atomic;
53
55
use core:: sync:: atomic:: AtomicUsize ;
54
56
@@ -116,7 +118,7 @@ impl<T: ?Sized> AtomicRefCell<T> {
116
118
pub fn borrow ( & self ) -> AtomicRef < T > {
117
119
match AtomicBorrowRef :: try_new ( & self . borrow ) {
118
120
Ok ( borrow) => AtomicRef {
119
- value : unsafe { & * self . value . get ( ) } ,
121
+ value : unsafe { NonNull :: new_unchecked ( self . value . get ( ) ) } ,
120
122
borrow,
121
123
} ,
122
124
Err ( s) => panic ! ( "{}" , s) ,
@@ -129,7 +131,7 @@ impl<T: ?Sized> AtomicRefCell<T> {
129
131
pub fn try_borrow ( & self ) -> Result < AtomicRef < T > , BorrowError > {
130
132
match AtomicBorrowRef :: try_new ( & self . borrow ) {
131
133
Ok ( borrow) => Ok ( AtomicRef {
132
- value : unsafe { & * self . value . get ( ) } ,
134
+ value : unsafe { NonNull :: new_unchecked ( self . value . get ( ) ) } ,
133
135
borrow,
134
136
} ) ,
135
137
Err ( _) => Err ( BorrowError { _private : ( ) } ) ,
@@ -141,8 +143,9 @@ impl<T: ?Sized> AtomicRefCell<T> {
141
143
pub fn borrow_mut ( & self ) -> AtomicRefMut < T > {
142
144
match AtomicBorrowRefMut :: try_new ( & self . borrow ) {
143
145
Ok ( borrow) => AtomicRefMut {
144
- value : unsafe { & mut * self . value . get ( ) } ,
146
+ value : unsafe { NonNull :: new_unchecked ( self . value . get ( ) ) } ,
145
147
borrow,
148
+ marker : PhantomData ,
146
149
} ,
147
150
Err ( s) => panic ! ( "{}" , s) ,
148
151
}
@@ -154,8 +157,9 @@ impl<T: ?Sized> AtomicRefCell<T> {
154
157
pub fn try_borrow_mut ( & self ) -> Result < AtomicRefMut < T > , BorrowMutError > {
155
158
match AtomicBorrowRefMut :: try_new ( & self . borrow ) {
156
159
Ok ( borrow) => Ok ( AtomicRefMut {
157
- value : unsafe { & mut * self . value . get ( ) } ,
160
+ value : unsafe { NonNull :: new_unchecked ( self . value . get ( ) ) } ,
158
161
borrow,
162
+ marker : PhantomData ,
159
163
} ) ,
160
164
Err ( _) => Err ( BorrowMutError { _private : ( ) } ) ,
161
165
}
@@ -366,16 +370,22 @@ impl<'b> Clone for AtomicBorrowRef<'b> {
366
370
367
371
/// A wrapper type for an immutably borrowed value from an `AtomicRefCell<T>`.
368
372
pub struct AtomicRef < ' b , T : ?Sized + ' b > {
369
- value : & ' b T ,
373
+ value : NonNull < T > ,
370
374
borrow : AtomicBorrowRef < ' b > ,
371
375
}
372
376
377
+ // SAFETY: `AtomicRef<'_, T> acts as a reference. `AtomicBorrowRef` is a
378
+ // reference to an atomic.
379
+ unsafe impl < ' b , T : ?Sized + ' b > Sync for AtomicRef < ' b , T > where for < ' a > & ' a T : Sync { }
380
+ unsafe impl < ' b , T : ?Sized + ' b > Send for AtomicRef < ' b , T > where for < ' a > & ' a T : Send { }
381
+
373
382
impl < ' b , T : ?Sized > Deref for AtomicRef < ' b , T > {
374
383
type Target = T ;
375
384
376
385
#[ inline]
377
386
fn deref ( & self ) -> & T {
378
- self . value
387
+ // SAFETY: We hold shared borrow of the value.
388
+ unsafe { self . value . as_ref ( ) }
379
389
}
380
390
}
381
391
@@ -396,7 +406,7 @@ impl<'b, T: ?Sized> AtomicRef<'b, T> {
396
406
F : FnOnce ( & T ) -> & U ,
397
407
{
398
408
AtomicRef {
399
- value : f ( orig. value ) ,
409
+ value : NonNull :: from ( f ( & * orig) ) ,
400
410
borrow : orig. borrow ,
401
411
}
402
412
}
@@ -408,7 +418,7 @@ impl<'b, T: ?Sized> AtomicRef<'b, T> {
408
418
F : FnOnce ( & T ) -> Option < & U > ,
409
419
{
410
420
Some ( AtomicRef {
411
- value : f ( orig. value ) ? ,
421
+ value : NonNull :: from ( f ( & * orig) ? ) ,
412
422
borrow : orig. borrow ,
413
423
} )
414
424
}
@@ -418,60 +428,75 @@ impl<'b, T: ?Sized> AtomicRefMut<'b, T> {
418
428
/// Make a new `AtomicRefMut` for a component of the borrowed data, e.g. an enum
419
429
/// variant.
420
430
#[ inline]
421
- pub fn map < U : ?Sized , F > ( orig : AtomicRefMut < ' b , T > , f : F ) -> AtomicRefMut < ' b , U >
431
+ pub fn map < U : ?Sized , F > ( mut orig : AtomicRefMut < ' b , T > , f : F ) -> AtomicRefMut < ' b , U >
422
432
where
423
433
F : FnOnce ( & mut T ) -> & mut U ,
424
434
{
425
435
AtomicRefMut {
426
- value : f ( orig. value ) ,
436
+ value : NonNull :: from ( f ( & mut * orig) ) ,
427
437
borrow : orig. borrow ,
438
+ marker : PhantomData ,
428
439
}
429
440
}
430
441
431
442
/// Make a new `AtomicRefMut` for an optional component of the borrowed data.
432
443
#[ inline]
433
- pub fn filter_map < U : ?Sized , F > ( orig : AtomicRefMut < ' b , T > , f : F ) -> Option < AtomicRefMut < ' b , U > >
444
+ pub fn filter_map < U : ?Sized , F > (
445
+ mut orig : AtomicRefMut < ' b , T > ,
446
+ f : F ,
447
+ ) -> Option < AtomicRefMut < ' b , U > >
434
448
where
435
449
F : FnOnce ( & mut T ) -> Option < & mut U > ,
436
450
{
437
451
Some ( AtomicRefMut {
438
- value : f ( orig. value ) ? ,
452
+ value : NonNull :: from ( f ( & mut * orig) ? ) ,
439
453
borrow : orig. borrow ,
454
+ marker : PhantomData ,
440
455
} )
441
456
}
442
457
}
443
458
444
459
/// A wrapper type for a mutably borrowed value from an `AtomicRefCell<T>`.
445
460
pub struct AtomicRefMut < ' b , T : ?Sized + ' b > {
446
- value : & ' b mut T ,
461
+ value : NonNull < T > ,
447
462
borrow : AtomicBorrowRefMut < ' b > ,
463
+ // `NonNull` is covariant over `T`, but this is used in place of a mutable
464
+ // reference so we need to be invariant over `T`.
465
+ marker : PhantomData < & ' b mut T > ,
448
466
}
449
467
468
+ // SAFETY: `AtomicRefMut<'_, T> acts as a mutable reference.
469
+ // `AtomicBorrowRefMut` is a reference to an atomic.
470
+ unsafe impl < ' b , T : ?Sized + ' b > Sync for AtomicRefMut < ' b , T > where for < ' a > & ' a mut T : Sync { }
471
+ unsafe impl < ' b , T : ?Sized + ' b > Send for AtomicRefMut < ' b , T > where for < ' a > & ' a mut T : Send { }
472
+
450
473
impl < ' b , T : ?Sized > Deref for AtomicRefMut < ' b , T > {
451
474
type Target = T ;
452
475
453
476
#[ inline]
454
477
fn deref ( & self ) -> & T {
455
- self . value
478
+ // SAFETY: We hold an exclusive borrow of the value.
479
+ unsafe { self . value . as_ref ( ) }
456
480
}
457
481
}
458
482
459
483
impl < ' b , T : ?Sized > DerefMut for AtomicRefMut < ' b , T > {
460
484
#[ inline]
461
485
fn deref_mut ( & mut self ) -> & mut T {
462
- self . value
486
+ // SAFETY: We hold an exclusive borrow of the value.
487
+ unsafe { self . value . as_mut ( ) }
463
488
}
464
489
}
465
490
466
491
impl < ' b , T : ?Sized + Debug + ' b > Debug for AtomicRef < ' b , T > {
467
492
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
468
- self . value . fmt ( f)
493
+ < T as Debug > :: fmt ( self , f)
469
494
}
470
495
}
471
496
472
497
impl < ' b , T : ?Sized + Debug + ' b > Debug for AtomicRefMut < ' b , T > {
473
498
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
474
- self . value . fmt ( f)
499
+ < T as Debug > :: fmt ( self , f)
475
500
}
476
501
}
477
502
0 commit comments