@@ -255,6 +255,7 @@ use crate::fmt::{self, Debug, Display};
255
255
use crate :: marker:: { PhantomData , PointerLike , Unsize } ;
256
256
use crate :: mem;
257
257
use crate :: ops:: { CoerceUnsized , Deref , DerefMut , DerefPure , DispatchFromDyn } ;
258
+ use crate :: panic:: const_panic;
258
259
use crate :: pin:: PinCoerceUnsized ;
259
260
use crate :: ptr:: { self , NonNull } ;
260
261
@@ -787,16 +788,24 @@ impl Display for BorrowMutError {
787
788
#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
788
789
#[ track_caller]
789
790
#[ 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
+ )
792
797
}
793
798
794
799
// This ensures the panicking code is outlined from `borrow` for `RefCell`.
795
800
#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
796
801
#[ track_caller]
797
802
#[ 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
+ )
800
809
}
801
810
802
811
// Positive values represent the number of `Ref` active. Negative values
@@ -816,12 +825,12 @@ type BorrowFlag = isize;
816
825
const UNUSED : BorrowFlag = 0 ;
817
826
818
827
#[ inline( always) ]
819
- fn is_writing ( x : BorrowFlag ) -> bool {
828
+ const fn is_writing ( x : BorrowFlag ) -> bool {
820
829
x < UNUSED
821
830
}
822
831
823
832
#[ inline( always) ]
824
- fn is_reading ( x : BorrowFlag ) -> bool {
833
+ const fn is_reading ( x : BorrowFlag ) -> bool {
825
834
x > UNUSED
826
835
}
827
836
@@ -890,8 +899,9 @@ impl<T> RefCell<T> {
890
899
#[ stable( feature = "refcell_replace" , since = "1.24.0" ) ]
891
900
#[ track_caller]
892
901
#[ 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)
895
905
}
896
906
897
907
/// Replaces the wrapped value with a new one computed from `f`, returning
@@ -941,7 +951,8 @@ impl<T> RefCell<T> {
941
951
/// ```
942
952
#[ inline]
943
953
#[ 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 ) {
945
956
mem:: swap ( & mut * self . borrow_mut ( ) , & mut * other. borrow_mut ( ) )
946
957
}
947
958
}
@@ -981,7 +992,8 @@ impl<T: ?Sized> RefCell<T> {
981
992
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
982
993
#[ inline]
983
994
#[ 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 > {
985
997
match self . try_borrow ( ) {
986
998
Ok ( b) => b,
987
999
Err ( err) => panic_already_mutably_borrowed ( err) ,
@@ -1016,14 +1028,15 @@ impl<T: ?Sized> RefCell<T> {
1016
1028
#[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
1017
1029
#[ inline]
1018
1030
#[ 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 > {
1020
1033
match BorrowRef :: new ( & self . borrow ) {
1021
1034
Some ( b) => {
1022
1035
#[ cfg( feature = "debug_refcell" ) ]
1023
1036
{
1024
1037
// `borrowed_at` is always the *first* active borrow
1025
1038
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 ( ) ) ) ;
1027
1040
}
1028
1041
}
1029
1042
@@ -1077,7 +1090,8 @@ impl<T: ?Sized> RefCell<T> {
1077
1090
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1078
1091
#[ inline]
1079
1092
#[ 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 > {
1081
1095
match self . try_borrow_mut ( ) {
1082
1096
Ok ( b) => b,
1083
1097
Err ( err) => panic_already_borrowed ( err) ,
@@ -1109,12 +1123,13 @@ impl<T: ?Sized> RefCell<T> {
1109
1123
#[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
1110
1124
#[ inline]
1111
1125
#[ 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 > {
1113
1128
match BorrowRefMut :: new ( & self . borrow ) {
1114
1129
Some ( b) => {
1115
1130
#[ cfg( feature = "debug_refcell" ) ]
1116
1131
{
1117
- self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1132
+ self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1118
1133
}
1119
1134
1120
1135
// SAFETY: `BorrowRefMut` guarantees unique access.
@@ -1145,7 +1160,8 @@ impl<T: ?Sized> RefCell<T> {
1145
1160
#[ stable( feature = "cell_as_ptr" , since = "1.12.0" ) ]
1146
1161
#[ rustc_as_ptr]
1147
1162
#[ 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 {
1149
1165
self . value . get ( )
1150
1166
}
1151
1167
@@ -1182,7 +1198,8 @@ impl<T: ?Sized> RefCell<T> {
1182
1198
/// ```
1183
1199
#[ inline]
1184
1200
#[ 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 {
1186
1203
self . value . get_mut ( )
1187
1204
}
1188
1205
@@ -1208,7 +1225,8 @@ impl<T: ?Sized> RefCell<T> {
1208
1225
/// assert!(c.try_borrow().is_ok());
1209
1226
/// ```
1210
1227
#[ 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 {
1212
1230
* self . borrow . get_mut ( ) = UNUSED ;
1213
1231
self . get_mut ( )
1214
1232
}
@@ -1242,7 +1260,8 @@ impl<T: ?Sized> RefCell<T> {
1242
1260
/// ```
1243
1261
#[ stable( feature = "borrow_state" , since = "1.37.0" ) ]
1244
1262
#[ 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 > {
1246
1265
if !is_writing ( self . borrow . get ( ) ) {
1247
1266
// SAFETY: We check that nobody is actively writing now, but it is
1248
1267
// the caller's responsibility to ensure that nobody writes until
@@ -1406,7 +1425,8 @@ struct BorrowRef<'b> {
1406
1425
1407
1426
impl < ' b > BorrowRef < ' b > {
1408
1427
#[ 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 > > {
1410
1430
let b = borrow. get ( ) . wrapping_add ( 1 ) ;
1411
1431
if !is_reading ( b) {
1412
1432
// Incrementing borrow can result in a non-reading value (<= 0) in these cases:
@@ -1423,33 +1443,41 @@ impl<'b> BorrowRef<'b> {
1423
1443
// 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
1424
1444
// 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize
1425
1445
// is large enough to represent having one more read borrow
1426
- borrow. set ( b) ;
1446
+ borrow. replace ( b) ;
1427
1447
Some ( BorrowRef { borrow } )
1428
1448
}
1429
1449
}
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
+ }
1430
1465
}
1431
1466
1432
- impl Drop for BorrowRef < ' _ > {
1467
+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1468
+ impl const Drop for BorrowRef < ' _ > {
1433
1469
#[ inline]
1434
1470
fn drop ( & mut self ) {
1435
1471
let borrow = self . borrow . get ( ) ;
1436
1472
debug_assert ! ( is_reading( borrow) ) ;
1437
- self . borrow . set ( borrow - 1 ) ;
1473
+ self . borrow . replace ( borrow - 1 ) ;
1438
1474
}
1439
1475
}
1440
1476
1441
1477
impl Clone for BorrowRef < ' _ > {
1442
1478
#[ inline]
1443
1479
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 ( )
1453
1481
}
1454
1482
}
1455
1483
@@ -1469,7 +1497,8 @@ pub struct Ref<'b, T: ?Sized + 'b> {
1469
1497
}
1470
1498
1471
1499
#[ 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 > {
1473
1502
type Target = T ;
1474
1503
1475
1504
#[ inline]
@@ -1494,7 +1523,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1494
1523
#[ stable( feature = "cell_extras" , since = "1.15.0" ) ]
1495
1524
#[ must_use]
1496
1525
#[ 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 > {
1498
1528
Ref { value : orig. value , borrow : orig. borrow . clone ( ) }
1499
1529
}
1500
1530
@@ -1616,7 +1646,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1616
1646
/// assert!(cell.try_borrow_mut().is_err());
1617
1647
/// ```
1618
1648
#[ 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 {
1620
1651
// By forgetting this Ref we ensure that the borrow counter in the RefCell can't go back to
1621
1652
// UNUSED within the lifetime `'b`. Resetting the reference tracking state would require a
1622
1653
// unique reference to the borrowed RefCell. No further mutable references can be created
@@ -1782,7 +1813,8 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1782
1813
/// assert!(cell.try_borrow_mut().is_err());
1783
1814
/// ```
1784
1815
#[ 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 {
1786
1818
// By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
1787
1819
// go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
1788
1820
// require a unique reference to the borrowed RefCell. No further references can be created
@@ -1798,25 +1830,27 @@ struct BorrowRefMut<'b> {
1798
1830
borrow : & ' b Cell < BorrowFlag > ,
1799
1831
}
1800
1832
1801
- impl Drop for BorrowRefMut < ' _ > {
1833
+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1834
+ impl const Drop for BorrowRefMut < ' _ > {
1802
1835
#[ inline]
1803
1836
fn drop ( & mut self ) {
1804
1837
let borrow = self . borrow . get ( ) ;
1805
1838
debug_assert ! ( is_writing( borrow) ) ;
1806
- self . borrow . set ( borrow + 1 ) ;
1839
+ self . borrow . replace ( borrow + 1 ) ;
1807
1840
}
1808
1841
}
1809
1842
1810
1843
impl < ' b > BorrowRefMut < ' b > {
1811
1844
#[ 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 > > {
1813
1847
// NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
1814
1848
// mutable reference, and so there must currently be no existing
1815
1849
// references. Thus, while clone increments the mutable refcount, here
1816
1850
// we explicitly only allow going from UNUSED to UNUSED - 1.
1817
1851
match borrow. get ( ) {
1818
1852
UNUSED => {
1819
- borrow. set ( UNUSED - 1 ) ;
1853
+ borrow. replace ( UNUSED - 1 ) ;
1820
1854
Some ( BorrowRefMut { borrow } )
1821
1855
}
1822
1856
_ => None ,
@@ -1855,7 +1889,8 @@ pub struct RefMut<'b, T: ?Sized + 'b> {
1855
1889
}
1856
1890
1857
1891
#[ 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 > {
1859
1894
type Target = T ;
1860
1895
1861
1896
#[ inline]
@@ -1866,7 +1901,8 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
1866
1901
}
1867
1902
1868
1903
#[ 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 > {
1870
1906
#[ inline]
1871
1907
fn deref_mut ( & mut self ) -> & mut T {
1872
1908
// SAFETY: the value is accessible as long as we hold our borrow.
0 commit comments