@@ -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
@@ -796,16 +797,24 @@ impl Display for BorrowMutError {
796797#[ cfg_attr( not( feature = "panic_immediate_abort" ) ,  inline( never) ) ]  
797798#[ track_caller]  
798799#[ cold]  
799- fn  panic_already_borrowed ( err :  BorrowMutError )  -> ! { 
800-     panic ! ( "already borrowed: {:?}" ,  err) 
800+ const  fn  panic_already_borrowed ( err :  BorrowMutError )  -> ! { 
801+     const_panic ! ( 
802+         "already borrowed" , 
803+         "already borrowed: {err:?}" , 
804+         err:  BorrowMutError  = err, 
805+     ) 
801806} 
802807
803808// This ensures the panicking code is outlined from `borrow` for `RefCell`. 
804809#[ cfg_attr( not( feature = "panic_immediate_abort" ) ,  inline( never) ) ]  
805810#[ track_caller]  
806811#[ cold]  
807- fn  panic_already_mutably_borrowed ( err :  BorrowError )  -> ! { 
808-     panic ! ( "already mutably borrowed: {:?}" ,  err) 
812+ const  fn  panic_already_mutably_borrowed ( err :  BorrowError )  -> ! { 
813+     const_panic ! ( 
814+         "already mutably borrowed" , 
815+         "already mutably borrowed: {err:?}" , 
816+         err:  BorrowError  = err, 
817+     ) 
809818} 
810819
811820// Positive values represent the number of `Ref` active. Negative values 
@@ -825,12 +834,12 @@ type BorrowFlag = isize;
825834const  UNUSED :  BorrowFlag  = 0 ; 
826835
827836#[ inline( always) ]  
828- fn  is_writing ( x :  BorrowFlag )  -> bool  { 
837+ const   fn  is_writing ( x :  BorrowFlag )  -> bool  { 
829838    x < UNUSED 
830839} 
831840
832841#[ inline( always) ]  
833- fn  is_reading ( x :  BorrowFlag )  -> bool  { 
842+ const   fn  is_reading ( x :  BorrowFlag )  -> bool  { 
834843    x > UNUSED 
835844} 
836845
@@ -899,8 +908,12 @@ impl<T> RefCell<T> {
899908    #[ stable( feature = "refcell_replace" ,  since = "1.24.0" ) ]  
900909    #[ track_caller]  
901910    #[ rustc_confusables( "swap" ) ]  
902-     pub  fn  replace ( & self ,  t :  T )  -> T  { 
903-         mem:: replace ( & mut  * self . borrow_mut ( ) ,  t) 
911+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
912+     pub  const  fn  replace ( & self ,  t :  T )  -> T  { 
913+         let  mut  s = self . borrow_mut ( ) ; 
914+         let  t = mem:: replace ( s. as_mut ( ) ,  t) ; 
915+         s. const_drop ( ) ; 
916+         t
904917    } 
905918
906919    /// Replaces the wrapped value with a new one computed from `f`, returning 
@@ -950,8 +963,13 @@ impl<T> RefCell<T> {
950963     /// ``` 
951964     #[ inline]  
952965    #[ stable( feature = "refcell_swap" ,  since = "1.24.0" ) ]  
953-     pub  fn  swap ( & self ,  other :  & Self )  { 
954-         mem:: swap ( & mut  * self . borrow_mut ( ) ,  & mut  * other. borrow_mut ( ) ) 
966+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
967+     pub  const  fn  swap ( & self ,  other :  & Self )  { 
968+         let  mut  s = self . borrow_mut ( ) ; 
969+         let  mut  o = other. borrow_mut ( ) ; 
970+         mem:: swap ( s. as_mut ( ) ,  o. as_mut ( ) ) ; 
971+         s. const_drop ( ) ; 
972+         o. const_drop ( ) ; 
955973    } 
956974} 
957975
@@ -990,7 +1008,8 @@ impl<T: ?Sized> RefCell<T> {
9901008     #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
9911009    #[ inline]  
9921010    #[ track_caller]  
993-     pub  fn  borrow ( & self )  -> Ref < ' _ ,  T >  { 
1011+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1012+     pub  const  fn  borrow ( & self )  -> Ref < ' _ ,  T >  { 
9941013        match  self . try_borrow ( )  { 
9951014            Ok ( b)  => b, 
9961015            Err ( err)  => panic_already_mutably_borrowed ( err) , 
@@ -1025,14 +1044,15 @@ impl<T: ?Sized> RefCell<T> {
10251044     #[ stable( feature = "try_borrow" ,  since = "1.13.0" ) ]  
10261045    #[ inline]  
10271046    #[ cfg_attr( feature = "debug_refcell" ,  track_caller) ]  
1028-     pub  fn  try_borrow ( & self )  -> Result < Ref < ' _ ,  T > ,  BorrowError >  { 
1047+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1048+     pub  const  fn  try_borrow ( & self )  -> Result < Ref < ' _ ,  T > ,  BorrowError >  { 
10291049        match  BorrowRef :: new ( & self . borrow )  { 
10301050            Some ( b)  => { 
10311051                #[ cfg( feature = "debug_refcell" ) ]  
10321052                { 
10331053                    // `borrowed_at` is always the *first* active borrow 
10341054                    if  b. borrow . get ( )  == 1  { 
1035-                         self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ; 
1055+                         self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ; 
10361056                    } 
10371057                } 
10381058
@@ -1086,7 +1106,8 @@ impl<T: ?Sized> RefCell<T> {
10861106     #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
10871107    #[ inline]  
10881108    #[ track_caller]  
1089-     pub  fn  borrow_mut ( & self )  -> RefMut < ' _ ,  T >  { 
1109+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1110+     pub  const  fn  borrow_mut ( & self )  -> RefMut < ' _ ,  T >  { 
10901111        match  self . try_borrow_mut ( )  { 
10911112            Ok ( b)  => b, 
10921113            Err ( err)  => panic_already_borrowed ( err) , 
@@ -1118,12 +1139,13 @@ impl<T: ?Sized> RefCell<T> {
11181139     #[ stable( feature = "try_borrow" ,  since = "1.13.0" ) ]  
11191140    #[ inline]  
11201141    #[ cfg_attr( feature = "debug_refcell" ,  track_caller) ]  
1121-     pub  fn  try_borrow_mut ( & self )  -> Result < RefMut < ' _ ,  T > ,  BorrowMutError >  { 
1142+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1143+     pub  const  fn  try_borrow_mut ( & self )  -> Result < RefMut < ' _ ,  T > ,  BorrowMutError >  { 
11221144        match  BorrowRefMut :: new ( & self . borrow )  { 
11231145            Some ( b)  => { 
11241146                #[ cfg( feature = "debug_refcell" ) ]  
11251147                { 
1126-                     self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ; 
1148+                     self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ; 
11271149                } 
11281150
11291151                // SAFETY: `BorrowRefMut` guarantees unique access. 
@@ -1154,7 +1176,8 @@ impl<T: ?Sized> RefCell<T> {
11541176    #[ stable( feature = "cell_as_ptr" ,  since = "1.12.0" ) ]  
11551177    #[ rustc_as_ptr]  
11561178    #[ rustc_never_returns_null_ptr]  
1157-     pub  fn  as_ptr ( & self )  -> * mut  T  { 
1179+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1180+     pub  const  fn  as_ptr ( & self )  -> * mut  T  { 
11581181        self . value . get ( ) 
11591182    } 
11601183
@@ -1187,7 +1210,8 @@ impl<T: ?Sized> RefCell<T> {
11871210     /// ``` 
11881211     #[ inline]  
11891212    #[ stable( feature = "cell_get_mut" ,  since = "1.11.0" ) ]  
1190-     pub  fn  get_mut ( & mut  self )  -> & mut  T  { 
1213+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1214+     pub  const  fn  get_mut ( & mut  self )  -> & mut  T  { 
11911215        self . value . get_mut ( ) 
11921216    } 
11931217
@@ -1213,7 +1237,8 @@ impl<T: ?Sized> RefCell<T> {
12131237     /// assert!(c.try_borrow().is_ok()); 
12141238     /// ``` 
12151239     #[ unstable( feature = "cell_leak" ,  issue = "69099" ) ]  
1216-     pub  fn  undo_leak ( & mut  self )  -> & mut  T  { 
1240+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1241+     pub  const  fn  undo_leak ( & mut  self )  -> & mut  T  { 
12171242        * self . borrow . get_mut ( )  = UNUSED ; 
12181243        self . get_mut ( ) 
12191244    } 
@@ -1247,7 +1272,8 @@ impl<T: ?Sized> RefCell<T> {
12471272     /// ``` 
12481273     #[ stable( feature = "borrow_state" ,  since = "1.37.0" ) ]  
12491274    #[ inline]  
1250-     pub  unsafe  fn  try_borrow_unguarded ( & self )  -> Result < & T ,  BorrowError >  { 
1275+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1276+     pub  const  unsafe  fn  try_borrow_unguarded ( & self )  -> Result < & T ,  BorrowError >  { 
12511277        if  !is_writing ( self . borrow . get ( ) )  { 
12521278            // SAFETY: We check that nobody is actively writing now, but it is 
12531279            // the caller's responsibility to ensure that nobody writes until 
@@ -1411,7 +1437,8 @@ struct BorrowRef<'b> {
14111437
14121438impl < ' b >  BorrowRef < ' b >  { 
14131439    #[ inline]  
1414-     fn  new ( borrow :  & ' b  Cell < BorrowFlag > )  -> Option < BorrowRef < ' b > >  { 
1440+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1441+     const  fn  new ( borrow :  & ' b  Cell < BorrowFlag > )  -> Option < BorrowRef < ' b > >  { 
14151442        let  b = borrow. get ( ) . wrapping_add ( 1 ) ; 
14161443        if  !is_reading ( b)  { 
14171444            // Incrementing borrow can result in a non-reading value (<= 0) in these cases: 
@@ -1428,10 +1455,23 @@ impl<'b> BorrowRef<'b> {
14281455            // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow 
14291456            // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize 
14301457            //    is large enough to represent having one more read borrow 
1431-             borrow. set ( b) ; 
1458+             borrow. replace ( b) ; 
14321459            Some ( BorrowRef  {  borrow } ) 
14331460        } 
14341461    } 
1462+     #[ inline]  
1463+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1464+     const  fn  clone ( & self )  -> Self  { 
1465+         // Since this Ref exists, we know the borrow flag 
1466+         // is a reading borrow. 
1467+         let  borrow = self . borrow . get ( ) ; 
1468+         debug_assert ! ( is_reading( borrow) ) ; 
1469+         // Prevent the borrow counter from overflowing into 
1470+         // a writing borrow. 
1471+         assert ! ( borrow != BorrowFlag :: MAX ) ; 
1472+         self . borrow . replace ( borrow + 1 ) ; 
1473+         BorrowRef  {  borrow :  self . borrow  } 
1474+     } 
14351475} 
14361476
14371477impl  Drop  for  BorrowRef < ' _ >  { 
@@ -1446,15 +1486,7 @@ impl Drop for BorrowRef<'_> {
14461486impl  Clone  for  BorrowRef < ' _ >  { 
14471487    #[ inline]  
14481488    fn  clone ( & self )  -> Self  { 
1449-         // Since this Ref exists, we know the borrow flag 
1450-         // is a reading borrow. 
1451-         let  borrow = self . borrow . get ( ) ; 
1452-         debug_assert ! ( is_reading( borrow) ) ; 
1453-         // Prevent the borrow counter from overflowing into 
1454-         // a writing borrow. 
1455-         assert ! ( borrow != BorrowFlag :: MAX ) ; 
1456-         self . borrow . set ( borrow + 1 ) ; 
1457-         BorrowRef  {  borrow :  self . borrow  } 
1489+         self . clone ( ) 
14581490    } 
14591491} 
14601492
@@ -1499,7 +1531,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14991531     #[ stable( feature = "cell_extras" ,  since = "1.15.0" ) ]  
15001532    #[ must_use]  
15011533    #[ inline]  
1502-     pub  fn  clone ( orig :  & Ref < ' b ,  T > )  -> Ref < ' b ,  T >  { 
1534+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1535+     pub  const  fn  clone ( orig :  & Ref < ' b ,  T > )  -> Ref < ' b ,  T >  { 
15031536        Ref  {  value :  orig. value ,  borrow :  orig. borrow . clone ( )  } 
15041537    } 
15051538
@@ -1621,7 +1654,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
16211654     /// assert!(cell.try_borrow_mut().is_err()); 
16221655     /// ``` 
16231656     #[ unstable( feature = "cell_leak" ,  issue = "69099" ) ]  
1624-     pub  fn  leak ( orig :  Ref < ' b ,  T > )  -> & ' b  T  { 
1657+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1658+     pub  const  fn  leak ( orig :  Ref < ' b ,  T > )  -> & ' b  T  { 
16251659        // By forgetting this Ref we ensure that the borrow counter in the RefCell can't go back to 
16261660        // UNUSED within the lifetime `'b`. Resetting the reference tracking state would require a 
16271661        // unique reference to the borrowed RefCell. No further mutable references can be created 
@@ -1643,6 +1677,21 @@ impl<T: ?Sized + fmt::Display> fmt::Display for Ref<'_, T> {
16431677} 
16441678
16451679impl < ' b ,  T :  ?Sized >  RefMut < ' b ,  T >  { 
1680+     #[ inline]  
1681+     const  fn  as_mut ( & mut  self )  -> & mut  T  { 
1682+         // SAFETY: the value is accessible as long as we hold our borrow. 
1683+         unsafe  {  self . value . as_mut ( )  } 
1684+     } 
1685+ 
1686+     #[ inline]  
1687+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1688+     const  fn  const_drop ( self )  { 
1689+         // SAFETY: only `borrow` is `Drop` 
1690+         let  borrow = unsafe  {  ptr:: read ( & self . borrow )  } ; 
1691+         mem:: forget ( self ) ; 
1692+         borrow. const_drop ( ) ; 
1693+     } 
1694+ 
16461695    /// Makes a new `RefMut` for a component of the borrowed data, e.g., an enum 
16471696     /// variant. 
16481697     /// 
@@ -1787,7 +1836,8 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
17871836     /// assert!(cell.try_borrow_mut().is_err()); 
17881837     /// ``` 
17891838     #[ unstable( feature = "cell_leak" ,  issue = "69099" ) ]  
1790-     pub  fn  leak ( mut  orig :  RefMut < ' b ,  T > )  -> & ' b  mut  T  { 
1839+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1840+     pub  const  fn  leak ( mut  orig :  RefMut < ' b ,  T > )  -> & ' b  mut  T  { 
17911841        // By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't 
17921842        // go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would 
17931843        // require a unique reference to the borrowed RefCell. No further references can be created 
@@ -1814,14 +1864,24 @@ impl Drop for BorrowRefMut<'_> {
18141864
18151865impl < ' b >  BorrowRefMut < ' b >  { 
18161866    #[ inline]  
1817-     fn  new ( borrow :  & ' b  Cell < BorrowFlag > )  -> Option < BorrowRefMut < ' b > >  { 
1867+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1868+     const  fn  const_drop ( self )  { 
1869+         let  borrow = self . borrow . get ( ) ; 
1870+         debug_assert ! ( is_writing( borrow) ) ; 
1871+         self . borrow . replace ( borrow + 1 ) ; 
1872+         mem:: forget ( self ) 
1873+     } 
1874+ 
1875+     #[ inline]  
1876+     #[ rustc_const_unstable( feature = "const_ref_cell" ,  issue = "137844" ) ]  
1877+     const  fn  new ( borrow :  & ' b  Cell < BorrowFlag > )  -> Option < BorrowRefMut < ' b > >  { 
18181878        // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial 
18191879        // mutable reference, and so there must currently be no existing 
18201880        // references. Thus, while clone increments the mutable refcount, here 
18211881        // we explicitly only allow going from UNUSED to UNUSED - 1. 
18221882        match  borrow. get ( )  { 
18231883            UNUSED  => { 
1824-                 borrow. set ( UNUSED  - 1 ) ; 
1884+                 borrow. replace ( UNUSED  - 1 ) ; 
18251885                Some ( BorrowRefMut  {  borrow } ) 
18261886            } 
18271887            _ => None , 
@@ -1874,8 +1934,7 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
18741934impl < T :  ?Sized >  DerefMut  for  RefMut < ' _ ,  T >  { 
18751935    #[ inline]  
18761936    fn  deref_mut ( & mut  self )  -> & mut  T  { 
1877-         // SAFETY: the value is accessible as long as we hold our borrow. 
1878-         unsafe  {  self . value . as_mut ( )  } 
1937+         self . as_mut ( ) 
18791938    } 
18801939} 
18811940
0 commit comments