@@ -197,7 +197,7 @@ use crate::fmt::{self, Debug, Display};
197
197
use crate :: marker:: Unsize ;
198
198
use crate :: mem;
199
199
use crate :: ops:: { CoerceUnsized , Deref , DerefMut } ;
200
- use crate :: ptr;
200
+ use crate :: ptr:: { self , NonNull } ;
201
201
202
202
/// A mutable memory location.
203
203
///
@@ -896,7 +896,8 @@ impl<T: ?Sized> RefCell<T> {
896
896
897
897
// SAFETY: `BorrowRef` ensures that there is only immutable access
898
898
// to the value while borrowed.
899
- Ok ( Ref { value : unsafe { & * self . value . get ( ) } , borrow : b } )
899
+ let value = unsafe { NonNull :: new_unchecked ( self . value . get ( ) ) } ;
900
+ Ok ( Ref { value, borrow : b } )
900
901
}
901
902
None => Err ( BorrowError {
902
903
// If a borrow occurred, then we must already have an outstanding borrow,
@@ -1314,7 +1315,9 @@ impl Clone for BorrowRef<'_> {
1314
1315
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1315
1316
#[ must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors" ]
1316
1317
pub struct Ref < ' b , T : ?Sized + ' b > {
1317
- value : & ' b T ,
1318
+ // NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
1319
+ // `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
1320
+ value : NonNull < T > ,
1318
1321
borrow : BorrowRef < ' b > ,
1319
1322
}
1320
1323
@@ -1324,7 +1327,8 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
1324
1327
1325
1328
#[ inline]
1326
1329
fn deref ( & self ) -> & T {
1327
- self . value
1330
+ // SAFETY: the value is accessible as long as we hold our borrow.
1331
+ unsafe { self . value . as_ref ( ) }
1328
1332
}
1329
1333
}
1330
1334
@@ -1368,7 +1372,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1368
1372
where
1369
1373
F : FnOnce ( & T ) -> & U ,
1370
1374
{
1371
- Ref { value : f ( orig. value ) , borrow : orig. borrow }
1375
+ Ref { value : NonNull :: from ( f ( & * orig) ) , borrow : orig. borrow }
1372
1376
}
1373
1377
1374
1378
/// Makes a new `Ref` for an optional component of the borrowed data. The
@@ -1399,8 +1403,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1399
1403
where
1400
1404
F : FnOnce ( & T ) -> Option < & U > ,
1401
1405
{
1402
- match f ( orig. value ) {
1403
- Some ( value) => Ok ( Ref { value, borrow : orig. borrow } ) ,
1406
+ match f ( & * orig) {
1407
+ Some ( value) => Ok ( Ref { value : NonNull :: from ( value ) , borrow : orig. borrow } ) ,
1404
1408
None => Err ( orig) ,
1405
1409
}
1406
1410
}
@@ -1431,9 +1435,12 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1431
1435
where
1432
1436
F : FnOnce ( & T ) -> ( & U , & V ) ,
1433
1437
{
1434
- let ( a, b) = f ( orig. value ) ;
1438
+ let ( a, b) = f ( & * orig) ;
1435
1439
let borrow = orig. borrow . clone ( ) ;
1436
- ( Ref { value : a, borrow } , Ref { value : b, borrow : orig. borrow } )
1440
+ (
1441
+ Ref { value : NonNull :: from ( a) , borrow } ,
1442
+ Ref { value : NonNull :: from ( b) , borrow : orig. borrow } ,
1443
+ )
1437
1444
}
1438
1445
1439
1446
/// Convert into a reference to the underlying data.
@@ -1467,7 +1474,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1467
1474
// unique reference to the borrowed RefCell. No further mutable references can be created
1468
1475
// from the original cell.
1469
1476
mem:: forget ( orig. borrow ) ;
1470
- orig. value
1477
+ // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
1478
+ unsafe { orig. value . as_ref ( ) }
1471
1479
}
1472
1480
}
1473
1481
0 commit comments