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,10 @@ 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
+ // `NonNull` is also covariant over `T`, just like we would have with `&T`.
1322
+ value : NonNull < T > ,
1318
1323
borrow : BorrowRef < ' b > ,
1319
1324
}
1320
1325
@@ -1324,7 +1329,8 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
1324
1329
1325
1330
#[ inline]
1326
1331
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 ( ) }
1328
1334
}
1329
1335
}
1330
1336
@@ -1368,7 +1374,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1368
1374
where
1369
1375
F : FnOnce ( & T ) -> & U ,
1370
1376
{
1371
- Ref { value : f ( orig. value ) , borrow : orig. borrow }
1377
+ Ref { value : NonNull :: from ( f ( & * orig) ) , borrow : orig. borrow }
1372
1378
}
1373
1379
1374
1380
/// Makes a new `Ref` for an optional component of the borrowed data. The
@@ -1399,8 +1405,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1399
1405
where
1400
1406
F : FnOnce ( & T ) -> Option < & U > ,
1401
1407
{
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 } ) ,
1404
1410
None => Err ( orig) ,
1405
1411
}
1406
1412
}
@@ -1431,9 +1437,12 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1431
1437
where
1432
1438
F : FnOnce ( & T ) -> ( & U , & V ) ,
1433
1439
{
1434
- let ( a, b) = f ( orig. value ) ;
1440
+ let ( a, b) = f ( & * orig) ;
1435
1441
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
+ )
1437
1446
}
1438
1447
1439
1448
/// Convert into a reference to the underlying data.
@@ -1467,7 +1476,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1467
1476
// unique reference to the borrowed RefCell. No further mutable references can be created
1468
1477
// from the original cell.
1469
1478
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 ( ) }
1471
1481
}
1472
1482
}
1473
1483
@@ -1507,13 +1517,12 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1507
1517
/// ```
1508
1518
#[ stable( feature = "cell_map" , since = "1.8.0" ) ]
1509
1519
#[ 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 >
1511
1521
where
1512
1522
F : FnOnce ( & mut T ) -> & mut U ,
1513
1523
{
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 }
1517
1526
}
1518
1527
1519
1528
/// Makes a new `RefMut` for an optional component of the borrowed data. The
@@ -1548,23 +1557,19 @@ 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
- // FIXME(nll-rfc#40): fix borrow-check
1556
- let RefMut { value, borrow } = orig;
1557
- let value = value as * mut T ;
1558
1564
// SAFETY: function holds onto an exclusive reference for the duration
1559
1565
// of its call through `orig`, and the pointer is only de-referenced
1560
1566
// inside of the function call never allowing the exclusive reference to
1561
1567
// 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 } )
1567
1571
}
1572
+ None => Err ( orig) ,
1568
1573
}
1569
1574
}
1570
1575
@@ -1596,15 +1601,18 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1596
1601
#[ stable( feature = "refcell_map_split" , since = "1.35.0" ) ]
1597
1602
#[ inline]
1598
1603
pub fn map_split < U : ?Sized , V : ?Sized , F > (
1599
- orig : RefMut < ' b , T > ,
1604
+ mut orig : RefMut < ' b , T > ,
1600
1605
f : F ,
1601
1606
) -> ( RefMut < ' b , U > , RefMut < ' b , V > )
1602
1607
where
1603
1608
F : FnOnce ( & mut T ) -> ( & mut U , & mut V ) ,
1604
1609
{
1605
- let ( a, b) = f ( orig. value ) ;
1606
1610
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
+ )
1608
1616
}
1609
1617
1610
1618
/// Convert into a mutable reference to the underlying data.
@@ -1630,14 +1638,15 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1630
1638
/// assert!(cell.try_borrow_mut().is_err());
1631
1639
/// ```
1632
1640
#[ 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 {
1634
1642
// By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
1635
1643
// go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
1636
1644
// require a unique reference to the borrowed RefCell. No further references can be created
1637
1645
// from the original cell within that lifetime, making the current borrow the only
1638
1646
// reference for the remaining lifetime.
1639
1647
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 ( ) }
1641
1650
}
1642
1651
}
1643
1652
@@ -1692,8 +1701,12 @@ impl<'b> BorrowRefMut<'b> {
1692
1701
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1693
1702
#[ must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors" ]
1694
1703
pub 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 > ,
1696
1707
borrow : BorrowRefMut < ' b > ,
1708
+ // `NonNull` is covariant over `T`, so we need to reintroduce invariance.
1709
+ marker : PhantomData < & ' b mut T > ,
1697
1710
}
1698
1711
1699
1712
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1702,15 +1715,17 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
1702
1715
1703
1716
#[ inline]
1704
1717
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 ( ) }
1706
1720
}
1707
1721
}
1708
1722
1709
1723
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1710
1724
impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
1711
1725
#[ inline]
1712
1726
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 ( ) }
1714
1729
}
1715
1730
}
1716
1731
0 commit comments