@@ -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
@@ -781,16 +782,24 @@ impl Display for BorrowMutError {
781
782
#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
782
783
#[ track_caller]
783
784
#[ 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
+ )
786
791
}
787
792
788
793
// This ensures the panicking code is outlined from `borrow` for `RefCell`.
789
794
#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
790
795
#[ track_caller]
791
796
#[ 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
+ )
794
803
}
795
804
796
805
// Positive values represent the number of `Ref` active. Negative values
@@ -810,12 +819,12 @@ type BorrowCounter = isize;
810
819
const UNUSED : BorrowCounter = 0 ;
811
820
812
821
#[ inline( always) ]
813
- fn is_writing ( x : BorrowCounter ) -> bool {
822
+ const fn is_writing ( x : BorrowCounter ) -> bool {
814
823
x < UNUSED
815
824
}
816
825
817
826
#[ inline( always) ]
818
- fn is_reading ( x : BorrowCounter ) -> bool {
827
+ const fn is_reading ( x : BorrowCounter ) -> bool {
819
828
x > UNUSED
820
829
}
821
830
@@ -884,8 +893,9 @@ impl<T> RefCell<T> {
884
893
#[ stable( feature = "refcell_replace" , since = "1.24.0" ) ]
885
894
#[ track_caller]
886
895
#[ 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)
889
899
}
890
900
891
901
/// Replaces the wrapped value with a new one computed from `f`, returning
@@ -935,7 +945,8 @@ impl<T> RefCell<T> {
935
945
/// ```
936
946
#[ inline]
937
947
#[ 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 ) {
939
950
mem:: swap ( & mut * self . borrow_mut ( ) , & mut * other. borrow_mut ( ) )
940
951
}
941
952
}
@@ -975,7 +986,8 @@ impl<T: ?Sized> RefCell<T> {
975
986
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
976
987
#[ inline]
977
988
#[ 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 > {
979
991
match self . try_borrow ( ) {
980
992
Ok ( b) => b,
981
993
Err ( err) => panic_already_mutably_borrowed ( err) ,
@@ -1010,14 +1022,15 @@ impl<T: ?Sized> RefCell<T> {
1010
1022
#[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
1011
1023
#[ inline]
1012
1024
#[ 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 > {
1014
1027
match BorrowRef :: new ( & self . borrow ) {
1015
1028
Some ( b) => {
1016
1029
#[ cfg( feature = "debug_refcell" ) ]
1017
1030
{
1018
1031
// `borrowed_at` is always the *first* active borrow
1019
1032
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 ( ) ) ) ;
1021
1034
}
1022
1035
}
1023
1036
@@ -1071,7 +1084,8 @@ impl<T: ?Sized> RefCell<T> {
1071
1084
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1072
1085
#[ inline]
1073
1086
#[ 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 > {
1075
1089
match self . try_borrow_mut ( ) {
1076
1090
Ok ( b) => b,
1077
1091
Err ( err) => panic_already_borrowed ( err) ,
@@ -1103,12 +1117,13 @@ impl<T: ?Sized> RefCell<T> {
1103
1117
#[ stable( feature = "try_borrow" , since = "1.13.0" ) ]
1104
1118
#[ inline]
1105
1119
#[ 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 > {
1107
1122
match BorrowRefMut :: new ( & self . borrow ) {
1108
1123
Some ( b) => {
1109
1124
#[ cfg( feature = "debug_refcell" ) ]
1110
1125
{
1111
- self . borrowed_at . set ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1126
+ self . borrowed_at . replace ( Some ( crate :: panic:: Location :: caller ( ) ) ) ;
1112
1127
}
1113
1128
1114
1129
// SAFETY: `BorrowRefMut` guarantees unique access.
@@ -1139,7 +1154,8 @@ impl<T: ?Sized> RefCell<T> {
1139
1154
#[ stable( feature = "cell_as_ptr" , since = "1.12.0" ) ]
1140
1155
#[ rustc_as_ptr]
1141
1156
#[ 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 {
1143
1159
self . value . get ( )
1144
1160
}
1145
1161
@@ -1176,7 +1192,8 @@ impl<T: ?Sized> RefCell<T> {
1176
1192
/// ```
1177
1193
#[ inline]
1178
1194
#[ 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 {
1180
1197
self . value . get_mut ( )
1181
1198
}
1182
1199
@@ -1202,7 +1219,8 @@ impl<T: ?Sized> RefCell<T> {
1202
1219
/// assert!(c.try_borrow().is_ok());
1203
1220
/// ```
1204
1221
#[ 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 {
1206
1224
* self . borrow . get_mut ( ) = UNUSED ;
1207
1225
self . get_mut ( )
1208
1226
}
@@ -1236,7 +1254,8 @@ impl<T: ?Sized> RefCell<T> {
1236
1254
/// ```
1237
1255
#[ stable( feature = "borrow_state" , since = "1.37.0" ) ]
1238
1256
#[ 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 > {
1240
1259
if !is_writing ( self . borrow . get ( ) ) {
1241
1260
// SAFETY: We check that nobody is actively writing now, but it is
1242
1261
// the caller's responsibility to ensure that nobody writes until
@@ -1400,7 +1419,7 @@ struct BorrowRef<'b> {
1400
1419
1401
1420
impl < ' b > BorrowRef < ' b > {
1402
1421
#[ inline]
1403
- fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRef < ' b > > {
1422
+ const fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRef < ' b > > {
1404
1423
let b = borrow. get ( ) . wrapping_add ( 1 ) ;
1405
1424
if !is_reading ( b) {
1406
1425
// Incrementing borrow can result in a non-reading value (<= 0) in these cases:
@@ -1417,22 +1436,24 @@ impl<'b> BorrowRef<'b> {
1417
1436
// 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
1418
1437
// 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize
1419
1438
// is large enough to represent having one more read borrow
1420
- borrow. set ( b) ;
1439
+ borrow. replace ( b) ;
1421
1440
Some ( BorrowRef { borrow } )
1422
1441
}
1423
1442
}
1424
1443
}
1425
1444
1426
- impl Drop for BorrowRef < ' _ > {
1445
+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1446
+ impl const Drop for BorrowRef < ' _ > {
1427
1447
#[ inline]
1428
1448
fn drop ( & mut self ) {
1429
1449
let borrow = self . borrow . get ( ) ;
1430
1450
debug_assert ! ( is_reading( borrow) ) ;
1431
- self . borrow . set ( borrow - 1 ) ;
1451
+ self . borrow . replace ( borrow - 1 ) ;
1432
1452
}
1433
1453
}
1434
1454
1435
- impl Clone for BorrowRef < ' _ > {
1455
+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1456
+ impl const Clone for BorrowRef < ' _ > {
1436
1457
#[ inline]
1437
1458
fn clone ( & self ) -> Self {
1438
1459
// Since this Ref exists, we know the borrow flag
@@ -1442,7 +1463,7 @@ impl Clone for BorrowRef<'_> {
1442
1463
// Prevent the borrow counter from overflowing into
1443
1464
// a writing borrow.
1444
1465
assert ! ( borrow != BorrowCounter :: MAX ) ;
1445
- self . borrow . set ( borrow + 1 ) ;
1466
+ self . borrow . replace ( borrow + 1 ) ;
1446
1467
BorrowRef { borrow : self . borrow }
1447
1468
}
1448
1469
}
@@ -1463,7 +1484,8 @@ pub struct Ref<'b, T: ?Sized + 'b> {
1463
1484
}
1464
1485
1465
1486
#[ 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 > {
1467
1489
type Target = T ;
1468
1490
1469
1491
#[ inline]
@@ -1488,7 +1510,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1488
1510
#[ stable( feature = "cell_extras" , since = "1.15.0" ) ]
1489
1511
#[ must_use]
1490
1512
#[ 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 > {
1492
1515
Ref { value : orig. value , borrow : orig. borrow . clone ( ) }
1493
1516
}
1494
1517
@@ -1610,7 +1633,8 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1610
1633
/// assert!(cell.try_borrow_mut().is_err());
1611
1634
/// ```
1612
1635
#[ 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 {
1614
1638
// By forgetting this Ref we ensure that the borrow counter in the RefCell can't go back to
1615
1639
// UNUSED within the lifetime `'b`. Resetting the reference tracking state would require a
1616
1640
// unique reference to the borrowed RefCell. No further mutable references can be created
@@ -1776,7 +1800,8 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1776
1800
/// assert!(cell.try_borrow_mut().is_err());
1777
1801
/// ```
1778
1802
#[ 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 {
1780
1805
// By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
1781
1806
// go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
1782
1807
// require a unique reference to the borrowed RefCell. No further references can be created
@@ -1792,25 +1817,26 @@ struct BorrowRefMut<'b> {
1792
1817
borrow : & ' b Cell < BorrowCounter > ,
1793
1818
}
1794
1819
1795
- impl Drop for BorrowRefMut < ' _ > {
1820
+ #[ rustc_const_unstable( feature = "const_ref_cell" , issue = "137844" ) ]
1821
+ impl const Drop for BorrowRefMut < ' _ > {
1796
1822
#[ inline]
1797
1823
fn drop ( & mut self ) {
1798
1824
let borrow = self . borrow . get ( ) ;
1799
1825
debug_assert ! ( is_writing( borrow) ) ;
1800
- self . borrow . set ( borrow + 1 ) ;
1826
+ self . borrow . replace ( borrow + 1 ) ;
1801
1827
}
1802
1828
}
1803
1829
1804
1830
impl < ' b > BorrowRefMut < ' b > {
1805
1831
#[ inline]
1806
- fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRefMut < ' b > > {
1832
+ const fn new ( borrow : & ' b Cell < BorrowCounter > ) -> Option < BorrowRefMut < ' b > > {
1807
1833
// NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
1808
1834
// mutable reference, and so there must currently be no existing
1809
1835
// references. Thus, while clone increments the mutable refcount, here
1810
1836
// we explicitly only allow going from UNUSED to UNUSED - 1.
1811
1837
match borrow. get ( ) {
1812
1838
UNUSED => {
1813
- borrow. set ( UNUSED - 1 ) ;
1839
+ borrow. replace ( UNUSED - 1 ) ;
1814
1840
Some ( BorrowRefMut { borrow } )
1815
1841
}
1816
1842
_ => None ,
@@ -1849,7 +1875,8 @@ pub struct RefMut<'b, T: ?Sized + 'b> {
1849
1875
}
1850
1876
1851
1877
#[ 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 > {
1853
1880
type Target = T ;
1854
1881
1855
1882
#[ inline]
@@ -1860,7 +1887,8 @@ impl<T: ?Sized> Deref for RefMut<'_, T> {
1860
1887
}
1861
1888
1862
1889
#[ 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 > {
1864
1892
#[ inline]
1865
1893
fn deref_mut ( & mut self ) -> & mut T {
1866
1894
// SAFETY: the value is accessible as long as we hold our borrow.
0 commit comments