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
- 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,
@@ -980,8 +981,9 @@ impl<T: ?Sized> RefCell<T> {
980
981
self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
981
982
}
982
983
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 } )
985
987
}
986
988
None => Err ( BorrowMutError {
987
989
// If a borrow occurred, then we must already have an outstanding borrow,
@@ -1314,7 +1316,9 @@ impl Clone for BorrowRef<'_> {
1314
1316
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1315
1317
#[ must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors" ]
1316
1318
pub 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
+ value : NonNull < T > ,
1318
1322
borrow : BorrowRef < ' b > ,
1319
1323
}
1320
1324
@@ -1324,7 +1328,8 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
1324
1328
1325
1329
#[ inline]
1326
1330
fn deref ( & self ) -> & T {
1327
- self . value
1331
+ // SAFETY: the value is accessible as long as we hold our borrow.
1332
+ unsafe { self . value . as_ref ( ) }
1328
1333
}
1329
1334
}
1330
1335
@@ -1368,7 +1373,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1368
1373
where
1369
1374
F : FnOnce ( & T ) -> & U ,
1370
1375
{
1371
- Ref { value : f ( orig. value ) , borrow : orig. borrow }
1376
+ Ref { value : NonNull :: from ( f ( & * orig) ) , borrow : orig. borrow }
1372
1377
}
1373
1378
1374
1379
/// Makes a new `Ref` for an optional component of the borrowed data. The
@@ -1399,8 +1404,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1399
1404
where
1400
1405
F : FnOnce ( & T ) -> Option < & U > ,
1401
1406
{
1402
- match f ( orig. value ) {
1403
- Some ( value) => Ok ( Ref { value, borrow : orig. borrow } ) ,
1407
+ match f ( & * orig) {
1408
+ Some ( value) => Ok ( Ref { value : NonNull :: from ( value ) , borrow : orig. borrow } ) ,
1404
1409
None => Err ( orig) ,
1405
1410
}
1406
1411
}
@@ -1431,9 +1436,12 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1431
1436
where
1432
1437
F : FnOnce ( & T ) -> ( & U , & V ) ,
1433
1438
{
1434
- let ( a, b) = f ( orig. value ) ;
1439
+ let ( a, b) = f ( & * orig) ;
1435
1440
let borrow = orig. borrow . clone ( ) ;
1436
- ( Ref { value : a, borrow } , Ref { value : b, borrow : orig. borrow } )
1441
+ (
1442
+ Ref { value : NonNull :: from ( a) , borrow } ,
1443
+ Ref { value : NonNull :: from ( b) , borrow : orig. borrow } ,
1444
+ )
1437
1445
}
1438
1446
1439
1447
/// Convert into a reference to the underlying data.
@@ -1467,7 +1475,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1467
1475
// unique reference to the borrowed RefCell. No further mutable references can be created
1468
1476
// from the original cell.
1469
1477
mem:: forget ( orig. borrow ) ;
1470
- orig. value
1478
+ // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
1479
+ unsafe { orig. value . as_ref ( ) }
1471
1480
}
1472
1481
}
1473
1482
@@ -1507,13 +1516,13 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1507
1516
/// ```
1508
1517
#[ stable( feature = "cell_map" , since = "1.8.0" ) ]
1509
1518
#[ inline]
1510
- 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 >
1511
1520
where
1512
1521
F : FnOnce ( & mut T ) -> & mut U ,
1513
1522
{
1514
1523
// 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 }
1517
1526
}
1518
1527
1519
1528
/// Makes a new `RefMut` for an optional component of the borrowed data. The
@@ -1548,23 +1557,20 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1548
1557
/// ```
1549
1558
#[ unstable( feature = "cell_filter_map" , reason = "recently added" , issue = "81061" ) ]
1550
1559
#[ 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 >
1552
1561
where
1553
1562
F : FnOnce ( & mut T ) -> Option < & mut U > ,
1554
1563
{
1555
1564
// FIXME(nll-rfc#40): fix borrow-check
1556
- let RefMut { value, borrow } = orig;
1557
- let value = value as * mut T ;
1558
1565
// SAFETY: function holds onto an exclusive reference for the duration
1559
1566
// of its call through `orig`, and the pointer is only de-referenced
1560
1567
// inside of the function call never allowing the exclusive reference to
1561
1568
// 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 } )
1569
+ match f ( & mut * orig) {
1570
+ Some ( value) => {
1571
+ Ok ( RefMut { value : NonNull :: from ( value) , borrow : orig. borrow , marker : PhantomData } )
1567
1572
}
1573
+ None => Err ( orig) ,
1568
1574
}
1569
1575
}
1570
1576
@@ -1596,15 +1602,18 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1596
1602
#[ stable( feature = "refcell_map_split" , since = "1.35.0" ) ]
1597
1603
#[ inline]
1598
1604
pub fn map_split < U : ?Sized , V : ?Sized , F > (
1599
- orig : RefMut < ' b , T > ,
1605
+ mut orig : RefMut < ' b , T > ,
1600
1606
f : F ,
1601
1607
) -> ( RefMut < ' b , U > , RefMut < ' b , V > )
1602
1608
where
1603
1609
F : FnOnce ( & mut T ) -> ( & mut U , & mut V ) ,
1604
1610
{
1605
- let ( a, b) = f ( orig. value ) ;
1606
1611
let borrow = orig. borrow . clone ( ) ;
1607
- ( 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
+ )
1608
1617
}
1609
1618
1610
1619
/// Convert into a mutable reference to the underlying data.
@@ -1630,14 +1639,15 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1630
1639
/// assert!(cell.try_borrow_mut().is_err());
1631
1640
/// ```
1632
1641
#[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1633
- pub fn leak ( orig : RefMut < ' b , T > ) -> & ' b mut T {
1642
+ pub fn leak ( mut orig : RefMut < ' b , T > ) -> & ' b mut T {
1634
1643
// By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
1635
1644
// go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
1636
1645
// require a unique reference to the borrowed RefCell. No further references can be created
1637
1646
// from the original cell within that lifetime, making the current borrow the only
1638
1647
// reference for the remaining lifetime.
1639
1648
mem:: forget ( orig. borrow ) ;
1640
- orig. value
1649
+ // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
1650
+ unsafe { orig. value . as_mut ( ) }
1641
1651
}
1642
1652
}
1643
1653
@@ -1692,8 +1702,12 @@ impl<'b> BorrowRefMut<'b> {
1692
1702
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1693
1703
#[ must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors" ]
1694
1704
pub struct RefMut < ' b , T : ?Sized + ' b > {
1695
- 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 > ,
1696
1708
borrow : BorrowRefMut < ' b > ,
1709
+ // NonNull is covariant over T, so we need to reintroduce invariance.
1710
+ marker : PhantomData < & ' b mut T > ,
1697
1711
}
1698
1712
1699
1713
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1702,15 +1716,17 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
1702
1716
1703
1717
#[ inline]
1704
1718
fn deref ( & self ) -> & T {
1705
- self . value
1719
+ // SAFETY: the value is accessible as long as we hold our borrow.
1720
+ unsafe { self . value . as_ref ( ) }
1706
1721
}
1707
1722
}
1708
1723
1709
1724
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1710
1725
impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
1711
1726
#[ inline]
1712
1727
fn deref_mut ( & mut self ) -> & mut T {
1713
- self . value
1728
+ // SAFETY: the value is accessible as long as we hold our borrow.
1729
+ unsafe { self . value . as_mut ( ) }
1714
1730
}
1715
1731
}
1716
1732
0 commit comments