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,9 @@ 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+ value : NonNull < T > ,
13181322 borrow : BorrowRef < ' b > ,
13191323}
13201324
@@ -1324,7 +1328,8 @@ impl<T: ?Sized> Deref for Ref<'_, T> {
13241328
13251329 #[ inline]
13261330 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 ( ) }
13281333 }
13291334}
13301335
@@ -1368,7 +1373,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
13681373 where
13691374 F : FnOnce ( & T ) -> & U ,
13701375 {
1371- Ref { value : f ( orig. value ) , borrow : orig. borrow }
1376+ Ref { value : NonNull :: from ( f ( & * orig) ) , borrow : orig. borrow }
13721377 }
13731378
13741379 /// Makes a new `Ref` for an optional component of the borrowed data. The
@@ -1399,8 +1404,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
13991404 where
14001405 F : FnOnce ( & T ) -> Option < & U > ,
14011406 {
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 } ) ,
14041409 None => Err ( orig) ,
14051410 }
14061411 }
@@ -1431,9 +1436,12 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14311436 where
14321437 F : FnOnce ( & T ) -> ( & U , & V ) ,
14331438 {
1434- let ( a, b) = f ( orig. value ) ;
1439+ let ( a, b) = f ( & * orig) ;
14351440 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+ )
14371445 }
14381446
14391447 /// Convert into a reference to the underlying data.
@@ -1467,7 +1475,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14671475 // unique reference to the borrowed RefCell. No further mutable references can be created
14681476 // from the original cell.
14691477 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 ( ) }
14711480 }
14721481}
14731482
@@ -1507,13 +1516,13 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
15071516 /// ```
15081517 #[ stable( feature = "cell_map" , since = "1.8.0" ) ]
15091518 #[ 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 >
15111520 where
15121521 F : FnOnce ( & mut T ) -> & mut U ,
15131522 {
15141523 // 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,20 @@ 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 {
15551564 // FIXME(nll-rfc#40): fix borrow-check
1556- let RefMut { value, borrow } = orig;
1557- let value = value as * mut T ;
15581565 // SAFETY: function holds onto an exclusive reference for the duration
15591566 // of its call through `orig`, and the pointer is only de-referenced
15601567 // inside of the function call never allowing the exclusive reference to
15611568 // 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 } )
15671572 }
1573+ None => Err ( orig) ,
15681574 }
15691575 }
15701576
@@ -1596,15 +1602,18 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
15961602 #[ stable( feature = "refcell_map_split" , since = "1.35.0" ) ]
15971603 #[ inline]
15981604 pub fn map_split < U : ?Sized , V : ?Sized , F > (
1599- orig : RefMut < ' b , T > ,
1605+ mut orig : RefMut < ' b , T > ,
16001606 f : F ,
16011607 ) -> ( RefMut < ' b , U > , RefMut < ' b , V > )
16021608 where
16031609 F : FnOnce ( & mut T ) -> ( & mut U , & mut V ) ,
16041610 {
1605- let ( a, b) = f ( orig. value ) ;
16061611 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+ )
16081617 }
16091618
16101619 /// Convert into a mutable reference to the underlying data.
@@ -1630,14 +1639,15 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
16301639 /// assert!(cell.try_borrow_mut().is_err());
16311640 /// ```
16321641 #[ 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 {
16341643 // By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
16351644 // go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
16361645 // require a unique reference to the borrowed RefCell. No further references can be created
16371646 // from the original cell within that lifetime, making the current borrow the only
16381647 // reference for the remaining lifetime.
16391648 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 ( ) }
16411651 }
16421652}
16431653
@@ -1692,8 +1702,12 @@ impl<'b> BorrowRefMut<'b> {
16921702#[ stable( feature = "rust1" , since = "1.0.0" ) ]
16931703#[ must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors" ]
16941704pub 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 > ,
16961708 borrow : BorrowRefMut < ' b > ,
1709+ // NonNull is covariant over T, so we need to reintroduce invariance.
1710+ marker : PhantomData < & ' b mut T > ,
16971711}
16981712
16991713#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1702,15 +1716,17 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
17021716
17031717 #[ inline]
17041718 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 ( ) }
17061721 }
17071722}
17081723
17091724#[ stable( feature = "rust1" , since = "1.0.0" ) ]
17101725impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
17111726 #[ inline]
17121727 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 ( ) }
17141730 }
17151731}
17161732
0 commit comments