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.

`