194194
195195use crate :: cmp:: Ordering ;
196196use crate :: fmt:: { self , Debug , Display } ;
197- use crate :: marker:: Unsize ;
197+ use crate :: marker:: { PhantomData , 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,
@@ -980,8 +981,9 @@ impl<T: ?Sized> RefCell<T> {
980981 self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
981982 }
982983
983- // SAFETY: `BorrowRef` guarantees unique access.
984- Ok ( RefMut { value : unsafe { & mut * self . value . get ( ) } , borrow : b } )
984+ // SAFETY: `BorrowRefMut` guarantees unique access.
985+ let value = unsafe { NonNull :: new_unchecked ( self . value . get ( ) ) } ;
986+ Ok ( RefMut { value, borrow : b, marker : PhantomData } )
985987 }
986988 None => Err ( BorrowMutError {
987989 // If a borrow occurred, then we must already have an outstanding borrow,
@@ -1314,7 +1316,10 @@ impl Clone for BorrowRef<'_> {
13141316#[ stable( feature = "rust1" , since = "1.0.0" ) ]
13151317#[ must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors" ]
13161318pub struct Ref < ' b , T : ?Sized + ' b > {
1317- value : & ' b T ,
1319+ // NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
1320+ // `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
1321+ // `NonNull` is also covariant over `T`, just like we would have with `&T`.
1322+ value : NonNull < T > ,
13181323 borrow : BorrowRef < ' b > ,
13191324}
13201325
@@ -1324,7 +1329,8 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
13241329
13251330 #[ inline]
13261331 fn deref ( & self ) -> & T {
1327- self . value
1332+ // SAFETY: the value is accessible as long as we hold our borrow.
1333+ unsafe { self . value . as_ref ( ) }
13281334 }
13291335}
13301336
@@ -1368,7 +1374,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
13681374 where
13691375 F : FnOnce ( & T ) -> & U ,
13701376 {
1371- Ref { value : f ( orig. value ) , borrow : orig. borrow }
1377+ Ref { value : NonNull :: from ( f ( & * orig) ) , borrow : orig. borrow }
13721378 }
13731379
13741380 /// Makes a new `Ref` for an optional component of the borrowed data. The
@@ -1399,8 +1405,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
13991405 where
14001406 F : FnOnce ( & T ) -> Option < & U > ,
14011407 {
1402- match f ( orig. value ) {
1403- Some ( value) => Ok ( Ref { value, borrow : orig. borrow } ) ,
1408+ match f ( & * orig) {
1409+ Some ( value) => Ok ( Ref { value : NonNull :: from ( value ) , borrow : orig. borrow } ) ,
14041410 None => Err ( orig) ,
14051411 }
14061412 }
@@ -1431,9 +1437,12 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14311437 where
14321438 F : FnOnce ( & T ) -> ( & U , & V ) ,
14331439 {
1434- let ( a, b) = f ( orig. value ) ;
1440+ let ( a, b) = f ( & * orig) ;
14351441 let borrow = orig. borrow . clone ( ) ;
1436- ( Ref { value : a, borrow } , Ref { value : b, borrow : orig. borrow } )
1442+ (
1443+ Ref { value : NonNull :: from ( a) , borrow } ,
1444+ Ref { value : NonNull :: from ( b) , borrow : orig. borrow } ,
1445+ )
14371446 }
14381447
14391448 /// Convert into a reference to the underlying data.
@@ -1467,7 +1476,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14671476 // unique reference to the borrowed RefCell. No further mutable references can be created
14681477 // from the original cell.
14691478 mem:: forget ( orig. borrow ) ;
1470- orig. value
1479+ // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
1480+ unsafe { orig. value . as_ref ( ) }
14711481 }
14721482}
14731483
@@ -1507,13 +1517,12 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
15071517 /// ```
15081518 #[ stable( feature = "cell_map" , since = "1.8.0" ) ]
15091519 #[ inline]
1510- pub fn map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> RefMut < ' b , U >
1520+ pub fn map < U : ?Sized , F > ( mut orig : RefMut < ' b , T > , f : F ) -> RefMut < ' b , U >
15111521 where
15121522 F : FnOnce ( & mut T ) -> & mut U ,
15131523 {
1514- // FIXME(nll-rfc#40): fix borrow-check
1515- let RefMut { value, borrow } = orig;
1516- RefMut { value : f ( value) , borrow }
1524+ let value = NonNull :: from ( f ( & mut * orig) ) ;
1525+ RefMut { value, borrow : orig. borrow , marker : PhantomData }
15171526 }
15181527
15191528 /// Makes a new `RefMut` for an optional component of the borrowed data. The
@@ -1548,23 +1557,19 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
15481557 /// ```
15491558 #[ unstable( feature = "cell_filter_map" , reason = "recently added" , issue = "81061" ) ]
15501559 #[ inline]
1551- pub fn filter_map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> Result < RefMut < ' b , U > , Self >
1560+ pub fn filter_map < U : ?Sized , F > ( mut orig : RefMut < ' b , T > , f : F ) -> Result < RefMut < ' b , U > , Self >
15521561 where
15531562 F : FnOnce ( & mut T ) -> Option < & mut U > ,
15541563 {
1555- // FIXME(nll-rfc#40): fix borrow-check
1556- let RefMut { value, borrow } = orig;
1557- let value = value as * mut T ;
15581564 // SAFETY: function holds onto an exclusive reference for the duration
15591565 // of its call through `orig`, and the pointer is only de-referenced
15601566 // inside of the function call never allowing the exclusive reference to
15611567 // escape.
1562- match f ( unsafe { & mut * value } ) {
1563- Some ( value) => Ok ( RefMut { value, borrow } ) ,
1564- None => {
1565- // SAFETY: same as above.
1566- Err ( RefMut { value : unsafe { & mut * value } , borrow } )
1568+ match f ( & mut * orig) {
1569+ Some ( value) => {
1570+ Ok ( RefMut { value : NonNull :: from ( value) , borrow : orig. borrow , marker : PhantomData } )
15671571 }
1572+ None => Err ( orig) ,
15681573 }
15691574 }
15701575
@@ -1596,15 +1601,18 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
15961601 #[ stable( feature = "refcell_map_split" , since = "1.35.0" ) ]
15971602 #[ inline]
15981603 pub fn map_split < U : ?Sized , V : ?Sized , F > (
1599- orig : RefMut < ' b , T > ,
1604+ mut orig : RefMut < ' b , T > ,
16001605 f : F ,
16011606 ) -> ( RefMut < ' b , U > , RefMut < ' b , V > )
16021607 where
16031608 F : FnOnce ( & mut T ) -> ( & mut U , & mut V ) ,
16041609 {
1605- let ( a, b) = f ( orig. value ) ;
16061610 let borrow = orig. borrow . clone ( ) ;
1607- ( RefMut { value : a, borrow } , RefMut { value : b, borrow : orig. borrow } )
1611+ let ( a, b) = f ( & mut * orig) ;
1612+ (
1613+ RefMut { value : NonNull :: from ( a) , borrow, marker : PhantomData } ,
1614+ RefMut { value : NonNull :: from ( b) , borrow : orig. borrow , marker : PhantomData } ,
1615+ )
16081616 }
16091617
16101618 /// Convert into a mutable reference to the underlying data.
@@ -1630,14 +1638,15 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
16301638 /// assert!(cell.try_borrow_mut().is_err());
16311639 /// ```
16321640 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1633- pub fn leak ( orig : RefMut < ' b , T > ) -> & ' b mut T {
1641+ pub fn leak ( mut orig : RefMut < ' b , T > ) -> & ' b mut T {
16341642 // By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
16351643 // go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
16361644 // require a unique reference to the borrowed RefCell. No further references can be created
16371645 // from the original cell within that lifetime, making the current borrow the only
16381646 // reference for the remaining lifetime.
16391647 mem:: forget ( orig. borrow ) ;
1640- orig. value
1648+ // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
1649+ unsafe { orig. value . as_mut ( ) }
16411650 }
16421651}
16431652
@@ -1692,8 +1701,12 @@ impl<'b> BorrowRefMut<'b> {
16921701#[ stable( feature = "rust1" , since = "1.0.0" ) ]
16931702#[ must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors" ]
16941703pub struct RefMut < ' b , T : ?Sized + ' b > {
1695- value : & ' b mut T ,
1704+ // NB: we use a pointer instead of `&'b mut T` to avoid `noalias` violations, because a
1705+ // `RefMut` argument doesn't hold exclusivity for its whole scope, only until it drops.
1706+ value : NonNull < T > ,
16961707 borrow : BorrowRefMut < ' b > ,
1708+ // `NonNull` is covariant over `T`, so we need to reintroduce invariance.
1709+ marker : PhantomData < & ' b mut T > ,
16971710}
16981711
16991712#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1702,15 +1715,17 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
17021715
17031716 #[ inline]
17041717 fn deref ( & self ) -> & T {
1705- self . value
1718+ // SAFETY: the value is accessible as long as we hold our borrow.
1719+ unsafe { self . value . as_ref ( ) }
17061720 }
17071721}
17081722
17091723#[ stable( feature = "rust1" , since = "1.0.0" ) ]
17101724impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
17111725 #[ inline]
17121726 fn deref_mut ( & mut self ) -> & mut T {
1713- self . value
1727+ // SAFETY: the value is accessible as long as we hold our borrow.
1728+ unsafe { self . value . as_mut ( ) }
17141729 }
17151730}
17161731
0 commit comments