194
194
195
195
use crate :: cmp:: Ordering ;
196
196
use crate :: fmt:: { self , Debug , Display } ;
197
- use crate :: marker:: Unsize ;
197
+ use crate :: marker:: { PhantomData , Unsize } ;
198
198
use crate :: mem;
199
199
use crate :: ops:: { CoerceUnsized , Deref , DerefMut } ;
200
200
use crate :: ptr:: { self , NonNull } ;
@@ -981,8 +981,9 @@ impl<T: ?Sized> RefCell<T> {
981
981
self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
982
982
}
983
983
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 } )
986
987
}
987
988
None => Err ( BorrowMutError {
988
989
// If a borrow occurred, then we must already have an outstanding borrow,
@@ -1515,13 +1516,13 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1515
1516
/// ```
1516
1517
#[ stable( feature = "cell_map" , since = "1.8.0" ) ]
1517
1518
#[ 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 >
1519
1520
where
1520
1521
F : FnOnce ( & mut T ) -> & mut U ,
1521
1522
{
1522
1523
// 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 }
1525
1526
}
1526
1527
1527
1528
/// Makes a new `RefMut` for an optional component of the borrowed data. The
@@ -1556,23 +1557,20 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1556
1557
/// ```
1557
1558
#[ unstable( feature = "cell_filter_map" , reason = "recently added" , issue = "81061" ) ]
1558
1559
#[ 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 >
1560
1561
where
1561
1562
F : FnOnce ( & mut T ) -> Option < & mut U > ,
1562
1563
{
1563
1564
// FIXME(nll-rfc#40): fix borrow-check
1564
- let RefMut { value, borrow } = orig;
1565
- let value = value as * mut T ;
1566
1565
// SAFETY: function holds onto an exclusive reference for the duration
1567
1566
// of its call through `orig`, and the pointer is only de-referenced
1568
1567
// inside of the function call never allowing the exclusive reference to
1569
1568
// 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 } )
1575
1572
}
1573
+ None => Err ( orig) ,
1576
1574
}
1577
1575
}
1578
1576
@@ -1604,15 +1602,18 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1604
1602
#[ stable( feature = "refcell_map_split" , since = "1.35.0" ) ]
1605
1603
#[ inline]
1606
1604
pub fn map_split < U : ?Sized , V : ?Sized , F > (
1607
- orig : RefMut < ' b , T > ,
1605
+ mut orig : RefMut < ' b , T > ,
1608
1606
f : F ,
1609
1607
) -> ( RefMut < ' b , U > , RefMut < ' b , V > )
1610
1608
where
1611
1609
F : FnOnce ( & mut T ) -> ( & mut U , & mut V ) ,
1612
1610
{
1613
- let ( a, b) = f ( orig. value ) ;
1614
1611
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
+ )
1616
1617
}
1617
1618
1618
1619
/// Convert into a mutable reference to the underlying data.
@@ -1638,14 +1639,15 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1638
1639
/// assert!(cell.try_borrow_mut().is_err());
1639
1640
/// ```
1640
1641
#[ 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 {
1642
1643
// By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
1643
1644
// go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
1644
1645
// require a unique reference to the borrowed RefCell. No further references can be created
1645
1646
// from the original cell within that lifetime, making the current borrow the only
1646
1647
// reference for the remaining lifetime.
1647
1648
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 ( ) }
1649
1651
}
1650
1652
}
1651
1653
@@ -1700,8 +1702,12 @@ impl<'b> BorrowRefMut<'b> {
1700
1702
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1701
1703
#[ must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors" ]
1702
1704
pub 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 > ,
1704
1708
borrow : BorrowRefMut < ' b > ,
1709
+ // NonNull is covariant over T, so we need to reintroduce invariance.
1710
+ marker : PhantomData < & ' b mut T > ,
1705
1711
}
1706
1712
1707
1713
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1710,15 +1716,17 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
1710
1716
1711
1717
#[ inline]
1712
1718
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 ( ) }
1714
1721
}
1715
1722
}
1716
1723
1717
1724
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1718
1725
impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
1719
1726
#[ inline]
1720
1727
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 ( ) }
1722
1730
}
1723
1731
}
1724
1732
0 commit comments