@@ -197,7 +197,7 @@ use crate::fmt::{self, Debug, Display};
197197use crate :: marker:: Unsize ;
198198use crate :: mem;
199199use crate :: ops:: { CoerceUnsized , Deref , DerefMut } ;
200- use crate :: ptr;
200+ use crate :: ptr:: { self , NonNull } ;
201201
202202/// A mutable memory location.
203203///
@@ -896,7 +896,8 @@ impl<T: ?Sized> RefCell<T> {
896896
897897 // SAFETY: `BorrowRef` ensures that there is only immutable access
898898 // 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 } )
900901 }
901902 None => Err ( BorrowError {
902903 // If a borrow occurred, then we must already have an outstanding borrow,
@@ -1314,7 +1315,9 @@ impl Clone for BorrowRef<'_> {
13141315#[ stable( feature = "rust1" , since = "1.0.0" ) ]
13151316#[ must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors" ]
13161317pub 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 > ,
13181321 borrow : BorrowRef < ' b > ,
13191322}
13201323
@@ -1324,7 +1327,8 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
13241327
13251328 #[ inline]
13261329 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 ( ) }
13281332 }
13291333}
13301334
@@ -1368,7 +1372,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
13681372 where
13691373 F : FnOnce ( & T ) -> & U ,
13701374 {
1371- Ref { value : f ( orig. value ) , borrow : orig. borrow }
1375+ Ref { value : NonNull :: from ( f ( & * orig) ) , borrow : orig. borrow }
13721376 }
13731377
13741378 /// Makes a new `Ref` for an optional component of the borrowed data. The
@@ -1399,8 +1403,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
13991403 where
14001404 F : FnOnce ( & T ) -> Option < & U > ,
14011405 {
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 } ) ,
14041408 None => Err ( orig) ,
14051409 }
14061410 }
@@ -1431,9 +1435,12 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14311435 where
14321436 F : FnOnce ( & T ) -> ( & U , & V ) ,
14331437 {
1434- let ( a, b) = f ( orig. value ) ;
1438+ let ( a, b) = f ( & * orig) ;
14351439 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+ )
14371444 }
14381445
14391446 /// Convert into a reference to the underlying data.
@@ -1467,7 +1474,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14671474 // unique reference to the borrowed RefCell. No further mutable references can be created
14681475 // from the original cell.
14691476 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 ( ) }
14711479 }
14721480}
14731481
0 commit comments