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 } ;
200200use crate :: ptr:: { self , NonNull } ;
@@ -981,8 +981,9 @@ impl<T: ?Sized> RefCell<T> {
981981 self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
982982 }
983983
984- // SAFETY: `BorrowRef` guarantees unique access.
985- 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 } )
986987 }
987988 None => Err ( BorrowMutError {
988989 // If a borrow occurred, then we must already have an outstanding borrow,
@@ -1515,13 +1516,13 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
15151516 /// ```
15161517 #[ stable( feature = "cell_map" , since = "1.8.0" ) ]
15171518 #[ inline]
1518- pub fn map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> RefMut < ' b , U >
1519+ pub fn map < U : ?Sized , F > ( mut orig : RefMut < ' b , T > , f : F ) -> RefMut < ' b , U >
15191520 where
15201521 F : FnOnce ( & mut T ) -> & mut U ,
15211522 {
15221523 // FIXME(nll-rfc#40): fix borrow-check
1523- let RefMut { value, borrow } = orig;
1524- RefMut { value : f ( value ) , borrow }
1524+ let value = NonNull :: from ( f ( & mut * orig) ) ;
1525+ RefMut { value, borrow : orig . borrow , marker : PhantomData }
15251526 }
15261527
15271528 /// Makes a new `RefMut` for an optional component of the borrowed data. The
@@ -1556,23 +1557,20 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
15561557 /// ```
15571558 #[ unstable( feature = "cell_filter_map" , reason = "recently added" , issue = "81061" ) ]
15581559 #[ inline]
1559- 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 >
15601561 where
15611562 F : FnOnce ( & mut T ) -> Option < & mut U > ,
15621563 {
15631564 // FIXME(nll-rfc#40): fix borrow-check
1564- let RefMut { value, borrow } = orig;
1565- let value = value as * mut T ;
15661565 // SAFETY: function holds onto an exclusive reference for the duration
15671566 // of its call through `orig`, and the pointer is only de-referenced
15681567 // inside of the function call never allowing the exclusive reference to
15691568 // escape.
1570- match f ( unsafe { & mut * value } ) {
1571- Some ( value) => Ok ( RefMut { value, borrow } ) ,
1572- None => {
1573- // SAFETY: same as above.
1574- Err ( RefMut { value : unsafe { & mut * value } , borrow } )
1569+ match f ( & mut * orig) {
1570+ Some ( value) => {
1571+ Ok ( RefMut { value : NonNull :: from ( value) , borrow : orig. borrow , marker : PhantomData } )
15751572 }
1573+ None => Err ( orig) ,
15761574 }
15771575 }
15781576
@@ -1604,15 +1602,18 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
16041602 #[ stable( feature = "refcell_map_split" , since = "1.35.0" ) ]
16051603 #[ inline]
16061604 pub fn map_split < U : ?Sized , V : ?Sized , F > (
1607- orig : RefMut < ' b , T > ,
1605+ mut orig : RefMut < ' b , T > ,
16081606 f : F ,
16091607 ) -> ( RefMut < ' b , U > , RefMut < ' b , V > )
16101608 where
16111609 F : FnOnce ( & mut T ) -> ( & mut U , & mut V ) ,
16121610 {
1613- let ( a, b) = f ( orig. value ) ;
16141611 let borrow = orig. borrow . clone ( ) ;
1615- ( RefMut { value : a, borrow } , RefMut { value : b, borrow : orig. borrow } )
1612+ let ( a, b) = f ( & mut * orig) ;
1613+ (
1614+ RefMut { value : NonNull :: from ( a) , borrow, marker : PhantomData } ,
1615+ RefMut { value : NonNull :: from ( b) , borrow : orig. borrow , marker : PhantomData } ,
1616+ )
16161617 }
16171618
16181619 /// Convert into a mutable reference to the underlying data.
@@ -1638,14 +1639,15 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
16381639 /// assert!(cell.try_borrow_mut().is_err());
16391640 /// ```
16401641 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1641- pub fn leak ( orig : RefMut < ' b , T > ) -> & ' b mut T {
1642+ pub fn leak ( mut orig : RefMut < ' b , T > ) -> & ' b mut T {
16421643 // By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
16431644 // go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
16441645 // require a unique reference to the borrowed RefCell. No further references can be created
16451646 // from the original cell within that lifetime, making the current borrow the only
16461647 // reference for the remaining lifetime.
16471648 mem:: forget ( orig. borrow ) ;
1648- orig. value
1649+ // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
1650+ unsafe { orig. value . as_mut ( ) }
16491651 }
16501652}
16511653
@@ -1700,8 +1702,12 @@ impl<'b> BorrowRefMut<'b> {
17001702#[ stable( feature = "rust1" , since = "1.0.0" ) ]
17011703#[ must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors" ]
17021704pub struct RefMut < ' b , T : ?Sized + ' b > {
1703- value : & ' b mut T ,
1705+ // NB: we use a pointer instead of `&'b mut T` to avoid `noalias` violations, because a
1706+ // `RefMut` argument doesn't hold exclusivity for its whole scope, only until it drops.
1707+ value : NonNull < T > ,
17041708 borrow : BorrowRefMut < ' b > ,
1709+ // NonNull is covariant over T, so we need to reintroduce invariance.
1710+ marker : PhantomData < & ' b mut T > ,
17051711}
17061712
17071713#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1710,15 +1716,17 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
17101716
17111717 #[ inline]
17121718 fn deref ( & self ) -> & T {
1713- self . value
1719+ // SAFETY: the value is accessible as long as we hold our borrow.
1720+ unsafe { self . value . as_ref ( ) }
17141721 }
17151722}
17161723
17171724#[ stable( feature = "rust1" , since = "1.0.0" ) ]
17181725impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
17191726 #[ inline]
17201727 fn deref_mut ( & mut self ) -> & mut T {
1721- self . value
1728+ // SAFETY: the value is accessible as long as we hold our borrow.
1729+ unsafe { self . value . as_mut ( ) }
17221730 }
17231731}
17241732
0 commit comments