Skip to content

Commit 4c48468

Browse files
Rollup merge of #142216 - nealsid:refcell-logging, r=tgross35
Miscellaneous RefCell cleanups - Clarify `RefCell` error messages when borrow rules are broken - Remove `Debug` impl for `BorrowError`/`BorrowMutError` since `#derive(Debug)` provides identical functionality - Rename `BorrowFlag` to `BorrowCounter`
2 parents be6b529 + 2fca05a commit 4c48468

File tree

1 file changed

+30
-36
lines changed

1 file changed

+30
-36
lines changed

library/core/src/cell.rs

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ impl<T, const N: usize> Cell<[T; N]> {
719719
#[rustc_diagnostic_item = "RefCell"]
720720
#[stable(feature = "rust1", since = "1.0.0")]
721721
pub struct RefCell<T: ?Sized> {
722-
borrow: Cell<BorrowFlag>,
722+
borrow: Cell<BorrowCounter>,
723723
// Stores the location of the earliest currently active borrow.
724724
// This gets updated whenever we go from having zero borrows
725725
// to having a single borrow. When a borrow occurs, this gets included
@@ -732,54 +732,48 @@ pub struct RefCell<T: ?Sized> {
732732
/// An error returned by [`RefCell::try_borrow`].
733733
#[stable(feature = "try_borrow", since = "1.13.0")]
734734
#[non_exhaustive]
735+
#[derive(Debug)]
735736
pub struct BorrowError {
736737
#[cfg(feature = "debug_refcell")]
737738
location: &'static crate::panic::Location<'static>,
738739
}
739740

740741
#[stable(feature = "try_borrow", since = "1.13.0")]
741-
impl Debug for BorrowError {
742+
impl Display for BorrowError {
742743
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
743-
let mut builder = f.debug_struct("BorrowError");
744-
745744
#[cfg(feature = "debug_refcell")]
746-
builder.field("location", self.location);
745+
let res = write!(
746+
f,
747+
"RefCell already mutably borrowed; a previous borrow was at {}",
748+
self.location
749+
);
747750

748-
builder.finish()
749-
}
750-
}
751+
#[cfg(not(feature = "debug_refcell"))]
752+
let res = Display::fmt("RefCell already mutably borrowed", f);
751753

752-
#[stable(feature = "try_borrow", since = "1.13.0")]
753-
impl Display for BorrowError {
754-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
755-
Display::fmt("already mutably borrowed", f)
754+
res
756755
}
757756
}
758757

759758
/// An error returned by [`RefCell::try_borrow_mut`].
760759
#[stable(feature = "try_borrow", since = "1.13.0")]
761760
#[non_exhaustive]
761+
#[derive(Debug)]
762762
pub struct BorrowMutError {
763763
#[cfg(feature = "debug_refcell")]
764764
location: &'static crate::panic::Location<'static>,
765765
}
766766

767767
#[stable(feature = "try_borrow", since = "1.13.0")]
768-
impl Debug for BorrowMutError {
768+
impl Display for BorrowMutError {
769769
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
770-
let mut builder = f.debug_struct("BorrowMutError");
771-
772770
#[cfg(feature = "debug_refcell")]
773-
builder.field("location", self.location);
771+
let res = write!(f, "RefCell already borrowed; a previous borrow was at {}", self.location);
774772

775-
builder.finish()
776-
}
777-
}
773+
#[cfg(not(feature = "debug_refcell"))]
774+
let res = Display::fmt("RefCell already borrowed", f);
778775

779-
#[stable(feature = "try_borrow", since = "1.13.0")]
780-
impl Display for BorrowMutError {
781-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
782-
Display::fmt("already borrowed", f)
776+
res
783777
}
784778
}
785779

@@ -788,15 +782,15 @@ impl Display for BorrowMutError {
788782
#[track_caller]
789783
#[cold]
790784
fn panic_already_borrowed(err: BorrowMutError) -> ! {
791-
panic!("already borrowed: {:?}", err)
785+
panic!("{err}")
792786
}
793787

794788
// This ensures the panicking code is outlined from `borrow` for `RefCell`.
795789
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
796790
#[track_caller]
797791
#[cold]
798792
fn panic_already_mutably_borrowed(err: BorrowError) -> ! {
799-
panic!("already mutably borrowed: {:?}", err)
793+
panic!("{err}")
800794
}
801795

802796
// Positive values represent the number of `Ref` active. Negative values
@@ -806,22 +800,22 @@ fn panic_already_mutably_borrowed(err: BorrowError) -> ! {
806800
//
807801
// `Ref` and `RefMut` are both two words in size, and so there will likely never
808802
// be enough `Ref`s or `RefMut`s in existence to overflow half of the `usize`
809-
// range. Thus, a `BorrowFlag` will probably never overflow or underflow.
803+
// range. Thus, a `BorrowCounter` will probably never overflow or underflow.
810804
// However, this is not a guarantee, as a pathological program could repeatedly
811805
// create and then mem::forget `Ref`s or `RefMut`s. Thus, all code must
812806
// explicitly check for overflow and underflow in order to avoid unsafety, or at
813807
// least behave correctly in the event that overflow or underflow happens (e.g.,
814808
// see BorrowRef::new).
815-
type BorrowFlag = isize;
816-
const UNUSED: BorrowFlag = 0;
809+
type BorrowCounter = isize;
810+
const UNUSED: BorrowCounter = 0;
817811

818812
#[inline(always)]
819-
fn is_writing(x: BorrowFlag) -> bool {
813+
fn is_writing(x: BorrowCounter) -> bool {
820814
x < UNUSED
821815
}
822816

823817
#[inline(always)]
824-
fn is_reading(x: BorrowFlag) -> bool {
818+
fn is_reading(x: BorrowCounter) -> bool {
825819
x > UNUSED
826820
}
827821

@@ -1401,12 +1395,12 @@ impl<T> From<T> for RefCell<T> {
14011395
impl<T: CoerceUnsized<U>, U> CoerceUnsized<RefCell<U>> for RefCell<T> {}
14021396

14031397
struct BorrowRef<'b> {
1404-
borrow: &'b Cell<BorrowFlag>,
1398+
borrow: &'b Cell<BorrowCounter>,
14051399
}
14061400

14071401
impl<'b> BorrowRef<'b> {
14081402
#[inline]
1409-
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
1403+
fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRef<'b>> {
14101404
let b = borrow.get().wrapping_add(1);
14111405
if !is_reading(b) {
14121406
// Incrementing borrow can result in a non-reading value (<= 0) in these cases:
@@ -1447,7 +1441,7 @@ impl Clone for BorrowRef<'_> {
14471441
debug_assert!(is_reading(borrow));
14481442
// Prevent the borrow counter from overflowing into
14491443
// a writing borrow.
1450-
assert!(borrow != BorrowFlag::MAX);
1444+
assert!(borrow != BorrowCounter::MAX);
14511445
self.borrow.set(borrow + 1);
14521446
BorrowRef { borrow: self.borrow }
14531447
}
@@ -1795,7 +1789,7 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
17951789
}
17961790

17971791
struct BorrowRefMut<'b> {
1798-
borrow: &'b Cell<BorrowFlag>,
1792+
borrow: &'b Cell<BorrowCounter>,
17991793
}
18001794

18011795
impl Drop for BorrowRefMut<'_> {
@@ -1809,7 +1803,7 @@ impl Drop for BorrowRefMut<'_> {
18091803

18101804
impl<'b> BorrowRefMut<'b> {
18111805
#[inline]
1812-
fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
1806+
fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRefMut<'b>> {
18131807
// NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
18141808
// mutable reference, and so there must currently be no existing
18151809
// references. Thus, while clone increments the mutable refcount, here
@@ -1833,7 +1827,7 @@ impl<'b> BorrowRefMut<'b> {
18331827
let borrow = self.borrow.get();
18341828
debug_assert!(is_writing(borrow));
18351829
// Prevent the borrow counter from underflowing.
1836-
assert!(borrow != BorrowFlag::MIN);
1830+
assert!(borrow != BorrowCounter::MIN);
18371831
self.borrow.set(borrow - 1);
18381832
BorrowRefMut { borrow: self.borrow }
18391833
}

0 commit comments

Comments
 (0)