@@ -255,6 +255,7 @@ use crate::fmt::{self, Debug, Display};
255255use crate :: marker:: { PhantomData , PointerLike , Unsize } ;
256256use crate :: mem;
257257use crate :: ops:: { CoerceUnsized , Deref , DerefMut , DerefPure , DispatchFromDyn } ;
258+ use crate :: panic:: const_panic;
258259use crate :: pin:: PinCoerceUnsized ;
259260use crate :: ptr:: { self , NonNull } ;
260261
@@ -787,16 +788,24 @@ impl Display for BorrowMutError {
787788#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
788789#[ track_caller]
789790#[ cold]
790- fn panic_already_borrowed ( err : BorrowMutError ) -> ! {
791- panic ! ( "already borrowed: {:?}" , err)
791+ const fn panic_already_borrowed ( err : BorrowMutError ) -> ! {
792+ const_panic ! (
793+ "already borrowed" ,
794+ "already borrowed: {err:?}" ,
795+ err: BorrowMutError = err,
796+ )
792797}
793798
794799// This ensures the panicking code is outlined from `borrow` for `RefCell`.
795800#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
796801#[ track_caller]
797802#[ cold]
798- fn panic_already_mutably_borrowed ( err : BorrowError ) -> ! {
799- panic ! ( "already mutably borrowed: {:?}" , err)
803+ const fn panic_already_mutably_borrowed ( err : BorrowError ) -> ! {
804+ const_panic ! (
805+ "already mutably borrowed" ,
806+ "already mutably borrowed: {err:?}" ,
807+ err: BorrowError = err,
808+ )
800809}
801810
802811// Positive values represent the number of `Ref` active. Negative values
@@ -816,12 +825,12 @@ type BorrowFlag = isize;
816825const UNUSED : BorrowFlag = 0 ;
817826
818827#[ inline( always) ]
819- fn is_writing ( x : BorrowFlag ) -> bool {
828+ const fn is_writing ( x : BorrowFlag ) -> bool {
820829 x < UNUSED
821830}
822831
823832#[ inline( always) ]
824- fn is_reading ( x : BorrowFlag ) -> bool {
833+ const fn is_reading ( x : BorrowFlag ) -> bool {
825834 x > UNUSED
826835}
827836
@@ -890,8 +899,9 @@ impl<T> RefCell<T> {
890899 #[ stable( feature = "refcell_replace" , since = "1.24.0" ) ]
891900 #[ track_caller]
892901 #[ rustc_confusables( "swap" ) ]
893- pub fn replace ( & self , t : T ) -> T {
894- mem:: replace ( & mut * self . borrow_mut ( ) , t)
902+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
903+ pub const fn replace ( & self , t : T ) -> T {
904+ mem:: replace ( & mut self . borrow_mut ( ) , t)
895905 }
896906
897907 /// Replaces the wrapped value with a new one computed from `f`, returning
@@ -941,7 +951,8 @@ impl<T> RefCell<T> {
941951 /// ```
942952 #[ inline]
943953 #[ stable( feature = "refcell_swap" , since = "1.24.0" ) ]
944- pub fn swap ( & self , other : & Self ) {
954+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
955+ pub const fn swap ( & self , other : & Self ) {
945956 mem:: swap ( & mut * self . borrow_mut ( ) , & mut * other. borrow_mut ( ) )
946957 }
947958}
@@ -981,7 +992,8 @@ impl<T: ?Sized> RefCell<T> {
981992 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
982993 #[ inline]
983994 #[ track_caller]
984- pub fn borrow ( & self ) -> Ref < ' _ , T > {
995+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
996+ pub const fn borrow ( & self ) -> Ref < ' _ , T > {
985997 match self . try_borrow ( ) {
986998 Ok ( b) => b,
987999 Err ( err) => panic_already_mutably_borrowed ( err) ,
@@ -1016,14 +1028,15 @@ impl<T: ?Sized> RefCell<T> {
10161028 #[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
10171029 #[ inline]
10181030 #[ cfg_attr( feature = "debug_refcell" , track_caller) ]
1019- pub fn try_borrow ( & self ) -> Result < Ref < ' _ , T > , BorrowError > {
1031+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1032+ pub const fn try_borrow ( & self ) -> Result < Ref < ' _ , T > , BorrowError > {
10201033 match BorrowRef :: new ( & self . borrow ) {
10211034 Some ( b) => {
10221035 #[ cfg( feature = "debug_refcell" ) ]
10231036 {
10241037 // `borrowed_at` is always the *first* active borrow
10251038 if b. borrow . get ( ) == 1 {
1026- self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1039+ self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
10271040 }
10281041 }
10291042
@@ -1077,7 +1090,8 @@ impl<T: ?Sized> RefCell<T> {
10771090 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10781091 #[ inline]
10791092 #[ track_caller]
1080- pub fn borrow_mut ( & self ) -> RefMut < ' _ , T > {
1093+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1094+ pub const fn borrow_mut ( & self ) -> RefMut < ' _ , T > {
10811095 match self . try_borrow_mut ( ) {
10821096 Ok ( b) => b,
10831097 Err ( err) => panic_already_borrowed ( err) ,
@@ -1109,12 +1123,13 @@ impl<T: ?Sized> RefCell<T> {
11091123 #[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
11101124 #[ inline]
11111125 #[ cfg_attr( feature = "debug_refcell" , track_caller) ]
1112- pub fn try_borrow_mut ( & self ) -> Result < RefMut < ' _ , T > , BorrowMutError > {
1126+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1127+ pub const fn try_borrow_mut ( & self ) -> Result < RefMut < ' _ , T > , BorrowMutError > {
11131128 match BorrowRefMut :: new ( & self . borrow ) {
11141129 Some ( b) => {
11151130 #[ cfg( feature = "debug_refcell" ) ]
11161131 {
1117- self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1132+ self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
11181133 }
11191134
11201135 // SAFETY: `BorrowRefMut` guarantees unique access.
@@ -1145,7 +1160,8 @@ impl<T: ?Sized> RefCell<T> {
11451160 #[ stable( feature = "cell_as_ptr" , since = "1.12.0" ) ]
11461161 #[ rustc_as_ptr]
11471162 #[ rustc_never_returns_null_ptr]
1148- pub fn as_ptr ( & self ) -> * mut T {
1163+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1164+ pub const fn as_ptr ( & self ) -> * mut T {
11491165 self . value . get ( )
11501166 }
11511167
@@ -1182,7 +1198,8 @@ impl<T: ?Sized> RefCell<T> {
11821198 /// ```
11831199 #[ inline]
11841200 #[ stable( feature = "cell_get_mut" , since = "1.11.0" ) ]
1185- pub fn get_mut ( & mut self ) -> & mut T {
1201+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1202+ pub const fn get_mut ( & mut self ) -> & mut T {
11861203 self . value . get_mut ( )
11871204 }
11881205
@@ -1208,7 +1225,8 @@ impl<T: ?Sized> RefCell<T> {
12081225 /// assert!(c.try_borrow().is_ok());
12091226 /// ```
12101227 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1211- pub fn undo_leak ( & mut self ) -> & mut T {
1228+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1229+ pub const fn undo_leak ( & mut self ) -> & mut T {
12121230 * self . borrow . get_mut ( ) = UNUSED ;
12131231 self . get_mut ( )
12141232 }
@@ -1242,7 +1260,8 @@ impl<T: ?Sized> RefCell<T> {
12421260 /// ```
12431261 #[ stable( feature = "borrow_state" , since = "1.37.0" ) ]
12441262 #[ inline]
1245- pub unsafe fn try_borrow_unguarded ( & self ) -> Result < & T , BorrowError > {
1263+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1264+ pub const unsafe fn try_borrow_unguarded ( & self ) -> Result < & T , BorrowError > {
12461265 if !is_writing ( self . borrow . get ( ) ) {
12471266 // SAFETY: We check that nobody is actively writing now, but it is
12481267 // the caller's responsibility to ensure that nobody writes until
@@ -1406,7 +1425,8 @@ struct BorrowRef<'b> {
14061425
14071426impl < ' b > BorrowRef < ' b > {
14081427 #[ inline]
1409- fn new ( borrow : & ' b Cell < BorrowFlag > ) -> Option < BorrowRef < ' b > > {
1428+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1429+ const fn new ( borrow : & ' b Cell < BorrowFlag > ) -> Option < BorrowRef < ' b > > {
14101430 let b = borrow. get ( ) . wrapping_add ( 1 ) ;
14111431 if !is_reading ( b) {
14121432 // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
@@ -1423,33 +1443,41 @@ impl<'b> BorrowRef<'b> {
14231443 // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
14241444 // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize
14251445 // is large enough to represent having one more read borrow
1426- borrow. set ( b) ;
1446+ borrow. replace ( b) ;
14271447 Some ( BorrowRef { borrow } )
14281448 }
14291449 }
1450+
1451+ /// FIXME(const-hack): `Clone` is not a `const_trait`, so work around that by making our own method
1452+ #[ inline]
1453+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1454+ const fn clone ( & self ) -> Self {
1455+ // Since this Ref exists, we know the borrow flag
1456+ // is a reading borrow.
1457+ let borrow = self . borrow . get ( ) ;
1458+ debug_assert ! ( is_reading( borrow) ) ;
1459+ // Prevent the borrow counter from overflowing into
1460+ // a writing borrow.
1461+ assert ! ( borrow != BorrowFlag :: MAX ) ;
1462+ self . borrow . replace ( borrow + 1 ) ;
1463+ BorrowRef { borrow : self . borrow }
1464+ }
14301465}
14311466
1432- impl Drop for BorrowRef < ' _ > {
1467+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1468+ impl const Drop for BorrowRef < ' _ > {
14331469 #[ inline]
14341470 fn drop ( & mut self ) {
14351471 let borrow = self . borrow . get ( ) ;
14361472 debug_assert ! ( is_reading( borrow) ) ;
1437- self . borrow . set ( borrow - 1 ) ;
1473+ self . borrow . replace ( borrow - 1 ) ;
14381474 }
14391475}
14401476
14411477impl Clone for BorrowRef < ' _ > {
14421478 #[ inline]
14431479 fn clone ( & self ) -> Self {
1444- // Since this Ref exists, we know the borrow flag
1445- // is a reading borrow.
1446- let borrow = self . borrow . get ( ) ;
1447- debug_assert ! ( is_reading( borrow) ) ;
1448- // Prevent the borrow counter from overflowing into
1449- // a writing borrow.
1450- assert ! ( borrow != BorrowFlag :: MAX ) ;
1451- self . borrow . set ( borrow + 1 ) ;
1452- BorrowRef { borrow : self . borrow }
1480+ self . clone ( )
14531481 }
14541482}
14551483
@@ -1469,7 +1497,8 @@ pub struct Ref<'b, T: ?Sized + 'b> {
14691497}
14701498
14711499#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1472- impl < T : ?Sized > Deref for Ref < ' _ , T > {
1500+ #[ rustc_const_unstable( feature = "const_deref" , issue = "88955" ) ]
1501+ impl < T : ?Sized > const Deref for Ref < ' _ , T > {
14731502 type Target = T ;
14741503
14751504 #[ inline]
@@ -1494,7 +1523,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14941523 #[ stable( feature = "cell_extras" , since = "1.15.0" ) ]
14951524 #[ must_use]
14961525 #[ inline]
1497- pub fn clone ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
1526+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1527+ pub const fn clone ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
14981528 Ref { value : orig. value , borrow : orig. borrow . clone ( ) }
14991529 }
15001530
@@ -1616,7 +1646,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
16161646 /// assert!(cell.try_borrow_mut().is_err());
16171647 /// ```
16181648 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1619- pub fn leak ( orig : Ref < ' b , T > ) -> & ' b T {
1649+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1650+ pub const fn leak ( orig : Ref < ' b , T > ) -> & ' b T {
16201651 // By forgetting this Ref we ensure that the borrow counter in the RefCell can't go back to
16211652 // UNUSED within the lifetime `'b`. Resetting the reference tracking state would require a
16221653 // unique reference to the borrowed RefCell. No further mutable references can be created
@@ -1782,7 +1813,8 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
17821813 /// assert!(cell.try_borrow_mut().is_err());
17831814 /// ```
17841815 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1785- pub fn leak ( mut orig : RefMut < ' b , T > ) -> & ' b mut T {
1816+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1817+ pub const fn leak ( mut orig : RefMut < ' b , T > ) -> & ' b mut T {
17861818 // By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
17871819 // go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
17881820 // require a unique reference to the borrowed RefCell. No further references can be created
@@ -1798,25 +1830,27 @@ struct BorrowRefMut<'b> {
17981830 borrow : & ' b Cell < BorrowFlag > ,
17991831}
18001832
1801- impl Drop for BorrowRefMut < ' _ > {
1833+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1834+ impl const Drop for BorrowRefMut < ' _ > {
18021835 #[ inline]
18031836 fn drop ( & mut self ) {
18041837 let borrow = self . borrow . get ( ) ;
18051838 debug_assert ! ( is_writing( borrow) ) ;
1806- self . borrow . set ( borrow + 1 ) ;
1839+ self . borrow . replace ( borrow + 1 ) ;
18071840 }
18081841}
18091842
18101843impl < ' b > BorrowRefMut < ' b > {
18111844 #[ inline]
1812- fn new ( borrow : & ' b Cell < BorrowFlag > ) -> Option < BorrowRefMut < ' b > > {
1845+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1846+ const fn new ( borrow : & ' b Cell < BorrowFlag > ) -> Option < BorrowRefMut < ' b > > {
18131847 // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
18141848 // mutable reference, and so there must currently be no existing
18151849 // references. Thus, while clone increments the mutable refcount, here
18161850 // we explicitly only allow going from UNUSED to UNUSED - 1.
18171851 match borrow. get ( ) {
18181852 UNUSED => {
1819- borrow. set ( UNUSED - 1 ) ;
1853+ borrow. replace ( UNUSED - 1 ) ;
18201854 Some ( BorrowRefMut { borrow } )
18211855 }
18221856 _ => None ,
@@ -1855,7 +1889,8 @@ pub struct RefMut<'b, T: ?Sized + 'b> {
18551889}
18561890
18571891#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1858- impl < T : ?Sized > Deref for RefMut < ' _ , T > {
1892+ #[ rustc_const_unstable( feature = "const_deref" , issue = "88955" ) ]
1893+ impl < T : ?Sized > const Deref for RefMut < ' _ , T > {
18591894 type Target = T ;
18601895
18611896 #[ inline]
@@ -1866,7 +1901,8 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
18661901}
18671902
18681903#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1869- impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
1904+ #[ rustc_const_unstable( feature = "const_deref" , issue = "88955" ) ]
1905+ impl < T : ?Sized > const DerefMut for RefMut < ' _ , T > {
18701906 #[ inline]
18711907 fn deref_mut ( & mut self ) -> & mut T {
18721908 // SAFETY: the value is accessible as long as we hold our borrow.
0 commit comments