@@ -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
@@ -781,16 +782,24 @@ impl Display for BorrowMutError {
781782#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
782783#[ track_caller]
783784#[ cold]
784- fn panic_already_borrowed ( err : BorrowMutError ) -> ! {
785- panic ! ( "{err}" )
785+ const fn panic_already_borrowed ( err : BorrowMutError ) -> ! {
786+ const_panic ! (
787+ "RefCell already borrowed" ,
788+ "{err}" ,
789+ err: BorrowMutError = err,
790+ )
786791}
787792
788793// This ensures the panicking code is outlined from `borrow` for `RefCell`.
789794#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
790795#[ track_caller]
791796#[ cold]
792- fn panic_already_mutably_borrowed ( err : BorrowError ) -> ! {
793- panic ! ( "{err}" )
797+ const fn panic_already_mutably_borrowed ( err : BorrowError ) -> ! {
798+ const_panic ! (
799+ "RefCell already mutably borrowed" ,
800+ "{err}" ,
801+ err: BorrowError = err,
802+ )
794803}
795804
796805// Positive values represent the number of `Ref` active. Negative values
@@ -810,12 +819,12 @@ type BorrowCounter = isize;
810819const UNUSED : BorrowCounter = 0 ;
811820
812821#[ inline( always) ]
813- fn is_writing ( x : BorrowCounter ) -> bool {
822+ const fn is_writing ( x : BorrowCounter ) -> bool {
814823 x < UNUSED
815824}
816825
817826#[ inline( always) ]
818- fn is_reading ( x : BorrowCounter ) -> bool {
827+ const fn is_reading ( x : BorrowCounter ) -> bool {
819828 x > UNUSED
820829}
821830
@@ -884,8 +893,9 @@ impl<T> RefCell<T> {
884893 #[ stable( feature = "refcell_replace" , since = "1.24.0" ) ]
885894 #[ track_caller]
886895 #[ rustc_confusables( "swap" ) ]
887- pub fn replace ( & self , t : T ) -> T {
888- mem:: replace ( & mut * self . borrow_mut ( ) , t)
896+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
897+ pub const fn replace ( & self , t : T ) -> T {
898+ mem:: replace ( & mut self . borrow_mut ( ) , t)
889899 }
890900
891901 /// Replaces the wrapped value with a new one computed from `f`, returning
@@ -935,7 +945,8 @@ impl<T> RefCell<T> {
935945 /// ```
936946 #[ inline]
937947 #[ stable( feature = "refcell_swap" , since = "1.24.0" ) ]
938- pub fn swap ( & self , other : & Self ) {
948+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
949+ pub const fn swap ( & self , other : & Self ) {
939950 mem:: swap ( & mut * self . borrow_mut ( ) , & mut * other. borrow_mut ( ) )
940951 }
941952}
@@ -975,7 +986,8 @@ impl<T: ?Sized> RefCell<T> {
975986 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
976987 #[ inline]
977988 #[ track_caller]
978- pub fn borrow ( & self ) -> Ref < ' _ , T > {
989+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
990+ pub const fn borrow ( & self ) -> Ref < ' _ , T > {
979991 match self . try_borrow ( ) {
980992 Ok ( b) => b,
981993 Err ( err) => panic_already_mutably_borrowed ( err) ,
@@ -1010,14 +1022,15 @@ impl<T: ?Sized> RefCell<T> {
10101022 #[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
10111023 #[ inline]
10121024 #[ cfg_attr( feature = "debug_refcell" , track_caller) ]
1013- pub fn try_borrow ( & self ) -> Result < Ref < ' _ , T > , BorrowError > {
1025+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1026+ pub const fn try_borrow ( & self ) -> Result < Ref < ' _ , T > , BorrowError > {
10141027 match BorrowRef :: new ( & self . borrow ) {
10151028 Some ( b) => {
10161029 #[ cfg( feature = "debug_refcell" ) ]
10171030 {
10181031 // `borrowed_at` is always the *first* active borrow
10191032 if b. borrow . get ( ) == 1 {
1020- self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1033+ self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
10211034 }
10221035 }
10231036
@@ -1071,7 +1084,8 @@ impl<T: ?Sized> RefCell<T> {
10711084 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
10721085 #[ inline]
10731086 #[ track_caller]
1074- pub fn borrow_mut ( & self ) -> RefMut < ' _ , T > {
1087+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1088+ pub const fn borrow_mut ( & self ) -> RefMut < ' _ , T > {
10751089 match self . try_borrow_mut ( ) {
10761090 Ok ( b) => b,
10771091 Err ( err) => panic_already_borrowed ( err) ,
@@ -1103,12 +1117,13 @@ impl<T: ?Sized> RefCell<T> {
11031117 #[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
11041118 #[ inline]
11051119 #[ cfg_attr( feature = "debug_refcell" , track_caller) ]
1106- pub fn try_borrow_mut ( & self ) -> Result < RefMut < ' _ , T > , BorrowMutError > {
1120+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1121+ pub const fn try_borrow_mut ( & self ) -> Result < RefMut < ' _ , T > , BorrowMutError > {
11071122 match BorrowRefMut :: new ( & self . borrow ) {
11081123 Some ( b) => {
11091124 #[ cfg( feature = "debug_refcell" ) ]
11101125 {
1111- self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1126+ self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
11121127 }
11131128
11141129 // SAFETY: `BorrowRefMut` guarantees unique access.
@@ -1139,7 +1154,8 @@ impl<T: ?Sized> RefCell<T> {
11391154 #[ stable( feature = "cell_as_ptr" , since = "1.12.0" ) ]
11401155 #[ rustc_as_ptr]
11411156 #[ rustc_never_returns_null_ptr]
1142- pub fn as_ptr ( & self ) -> * mut T {
1157+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1158+ pub const fn as_ptr ( & self ) -> * mut T {
11431159 self . value . get ( )
11441160 }
11451161
@@ -1176,7 +1192,8 @@ impl<T: ?Sized> RefCell<T> {
11761192 /// ```
11771193 #[ inline]
11781194 #[ stable( feature = "cell_get_mut" , since = "1.11.0" ) ]
1179- pub fn get_mut ( & mut self ) -> & mut T {
1195+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1196+ pub const fn get_mut ( & mut self ) -> & mut T {
11801197 self . value . get_mut ( )
11811198 }
11821199
@@ -1202,7 +1219,8 @@ impl<T: ?Sized> RefCell<T> {
12021219 /// assert!(c.try_borrow().is_ok());
12031220 /// ```
12041221 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1205- pub fn undo_leak ( & mut self ) -> & mut T {
1222+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1223+ pub const fn undo_leak ( & mut self ) -> & mut T {
12061224 * self . borrow . get_mut ( ) = UNUSED ;
12071225 self . get_mut ( )
12081226 }
@@ -1236,7 +1254,8 @@ impl<T: ?Sized> RefCell<T> {
12361254 /// ```
12371255 #[ stable( feature = "borrow_state" , since = "1.37.0" ) ]
12381256 #[ inline]
1239- pub unsafe fn try_borrow_unguarded ( & self ) -> Result < & T , BorrowError > {
1257+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1258+ pub const unsafe fn try_borrow_unguarded ( & self ) -> Result < & T , BorrowError > {
12401259 if !is_writing ( self . borrow . get ( ) ) {
12411260 // SAFETY: We check that nobody is actively writing now, but it is
12421261 // the caller's responsibility to ensure that nobody writes until
@@ -1400,7 +1419,7 @@ struct BorrowRef<'b> {
14001419
14011420impl < ' b > BorrowRef < ' b > {
14021421 #[ inline]
1403- fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRef < ' b > > {
1422+ const fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRef < ' b > > {
14041423 let b = borrow. get ( ) . wrapping_add ( 1 ) ;
14051424 if !is_reading ( b) {
14061425 // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
@@ -1417,22 +1436,24 @@ impl<'b> BorrowRef<'b> {
14171436 // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
14181437 // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize
14191438 // is large enough to represent having one more read borrow
1420- borrow. set ( b) ;
1439+ borrow. replace ( b) ;
14211440 Some ( BorrowRef { borrow } )
14221441 }
14231442 }
14241443}
14251444
1426- impl Drop for BorrowRef < ' _ > {
1445+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1446+ impl const Drop for BorrowRef < ' _ > {
14271447 #[ inline]
14281448 fn drop ( & mut self ) {
14291449 let borrow = self . borrow . get ( ) ;
14301450 debug_assert ! ( is_reading( borrow) ) ;
1431- self . borrow . set ( borrow - 1 ) ;
1451+ self . borrow . replace ( borrow - 1 ) ;
14321452 }
14331453}
14341454
1435- impl Clone for BorrowRef < ' _ > {
1455+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1456+ impl const Clone for BorrowRef < ' _ > {
14361457 #[ inline]
14371458 fn clone ( & self ) -> Self {
14381459 // Since this Ref exists, we know the borrow flag
@@ -1442,7 +1463,7 @@ impl Clone for BorrowRef<'_> {
14421463 // Prevent the borrow counter from overflowing into
14431464 // a writing borrow.
14441465 assert ! ( borrow != BorrowCounter :: MAX ) ;
1445- self . borrow . set ( borrow + 1 ) ;
1466+ self . borrow . replace ( borrow + 1 ) ;
14461467 BorrowRef { borrow : self . borrow }
14471468 }
14481469}
@@ -1463,7 +1484,8 @@ pub struct Ref<'b, T: ?Sized + 'b> {
14631484}
14641485
14651486#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1466- impl < T : ?Sized > Deref for Ref < ' _ , T > {
1487+ #[ rustc_const_unstable( feature = "const_deref" , issue = "88955" ) ]
1488+ impl < T : ?Sized > const Deref for Ref < ' _ , T > {
14671489 type Target = T ;
14681490
14691491 #[ inline]
@@ -1488,7 +1510,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
14881510 #[ stable( feature = "cell_extras" , since = "1.15.0" ) ]
14891511 #[ must_use]
14901512 #[ inline]
1491- pub fn clone ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
1513+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1514+ pub const fn clone ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
14921515 Ref { value : orig. value , borrow : orig. borrow . clone ( ) }
14931516 }
14941517
@@ -1610,7 +1633,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
16101633 /// assert!(cell.try_borrow_mut().is_err());
16111634 /// ```
16121635 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1613- pub fn leak ( orig : Ref < ' b , T > ) -> & ' b T {
1636+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1637+ pub const fn leak ( orig : Ref < ' b , T > ) -> & ' b T {
16141638 // By forgetting this Ref we ensure that the borrow counter in the RefCell can't go back to
16151639 // UNUSED within the lifetime `'b`. Resetting the reference tracking state would require a
16161640 // unique reference to the borrowed RefCell. No further mutable references can be created
@@ -1776,7 +1800,8 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
17761800 /// assert!(cell.try_borrow_mut().is_err());
17771801 /// ```
17781802 #[ unstable( feature = "cell_leak" , issue = "69099" ) ]
1779- pub fn leak ( mut orig : RefMut < ' b , T > ) -> & ' b mut T {
1803+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1804+ pub const fn leak ( mut orig : RefMut < ' b , T > ) -> & ' b mut T {
17801805 // By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
17811806 // go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
17821807 // require a unique reference to the borrowed RefCell. No further references can be created
@@ -1792,25 +1817,26 @@ struct BorrowRefMut<'b> {
17921817 borrow : & ' b Cell < BorrowCounter > ,
17931818}
17941819
1795- impl Drop for BorrowRefMut < ' _ > {
1820+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1821+ impl const Drop for BorrowRefMut < ' _ > {
17961822 #[ inline]
17971823 fn drop ( & mut self ) {
17981824 let borrow = self . borrow . get ( ) ;
17991825 debug_assert ! ( is_writing( borrow) ) ;
1800- self . borrow . set ( borrow + 1 ) ;
1826+ self . borrow . replace ( borrow + 1 ) ;
18011827 }
18021828}
18031829
18041830impl < ' b > BorrowRefMut < ' b > {
18051831 #[ inline]
1806- fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRefMut < ' b > > {
1832+ const fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRefMut < ' b > > {
18071833 // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
18081834 // mutable reference, and so there must currently be no existing
18091835 // references. Thus, while clone increments the mutable refcount, here
18101836 // we explicitly only allow going from UNUSED to UNUSED - 1.
18111837 match borrow. get ( ) {
18121838 UNUSED => {
1813- borrow. set ( UNUSED - 1 ) ;
1839+ borrow. replace ( UNUSED - 1 ) ;
18141840 Some ( BorrowRefMut { borrow } )
18151841 }
18161842 _ => None ,
@@ -1849,7 +1875,8 @@ pub struct RefMut<'b, T: ?Sized + 'b> {
18491875}
18501876
18511877#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1852- impl < T : ?Sized > Deref for RefMut < ' _ , T > {
1878+ #[ rustc_const_unstable( feature = "const_deref" , issue = "88955" ) ]
1879+ impl < T : ?Sized > const Deref for RefMut < ' _ , T > {
18531880 type Target = T ;
18541881
18551882 #[ inline]
@@ -1860,7 +1887,8 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
18601887}
18611888
18621889#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1863- impl < T : ?Sized > DerefMut for RefMut < ' _ , T > {
1890+ #[ rustc_const_unstable( feature = "const_deref" , issue = "88955" ) ]
1891+ impl < T : ?Sized > const DerefMut for RefMut < ' _ , T > {
18641892 #[ inline]
18651893 fn deref_mut ( & mut self ) -> & mut T {
18661894 // SAFETY: the value is accessible as long as we hold our borrow.
0 commit comments