make RefCell unstably const · rust-lang/rust@1f1000f (original) (raw)
`@@ -255,6 +255,7 @@ use crate::fmt::{self, Debug, Display};
`
255
255
`use crate:📑:{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 RefCell {
`
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 RefCell {
`
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 {
`
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) -> Option<BorrowRef<'b>> {
`
``
1422
`+
const fn new(borrow: &'b Cell) -> 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,
`
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) -> Option<BorrowRefMut<'b>> {
`
``
1832
`+
const fn new(borrow: &'b Cell) -> 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.
`