From 38811a1d31beac00e4b7c331341f557a3de2151a Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 19 Mar 2019 12:24:38 +0100 Subject: [PATCH] Introduce RefCell::try_borrow_unguarded This replaces RefCell::borrow_state to something that encodes the use case of Servo better. --- src/libcore/cell.rs | 87 ++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index fe5cc8bd274..c67ac26562f 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -569,18 +569,6 @@ pub struct RefCell { value: UnsafeCell, } -/// An enumeration of values returned from the `state` method on a `RefCell`. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -#[unstable(feature = "borrow_state", issue = "27733")] -pub enum BorrowState { - /// The cell is currently being read, there is at least one active `borrow`. - Reading, - /// The cell is currently being written to, there is an active `borrow_mut`. - Writing, - /// There are no outstanding borrows on this cell. - Unused, -} - /// An error returned by [`RefCell::try_borrow`](struct.RefCell.html#method.try_borrow). #[stable(feature = "try_borrow", since = "1.13.0")] pub struct BorrowError { @@ -765,43 +753,6 @@ impl RefCell { } impl RefCell { - /// Queries the current state of this `RefCell`. - /// - /// A return value of `BorrowState::Writing` signals that this `RefCell` - /// is currently mutably borrowed, while `BorrowState::Reading` signals - /// that it is immutably borrowed. - /// - /// This is mostly useful in rare use cases with `RefCell::as_ptr` to - /// access the data without changing its borrow state, use with care. - /// - /// # Examples - /// - /// ``` - /// #![feature(borrow_state)] - /// - /// use std::cell::{BorrowState, RefCell}; - /// - /// let c = RefCell::new(5); - /// - /// match c.borrow_state() { - /// BorrowState::Writing => println!("currently borrowed mutably"), - /// BorrowState::Reading => println!("currently borrowed immutably"), - /// BorrowState::Unused => println!("not borrowed"), - /// } - /// ``` - #[unstable(feature = "borrow_state", issue = "27733")] - #[inline] - pub fn borrow_state(&self) -> BorrowState { - let borrow = self.borrow.get(); - if is_writing(borrow) { - BorrowState::Writing - } else if is_reading(borrow) { - BorrowState::Reading - } else { - BorrowState::Unused - } - } - /// Immutably borrows the wrapped value. /// /// The borrow lasts until the returned `Ref` exits scope. Multiple @@ -1007,6 +958,44 @@ impl RefCell { &mut *self.value.get() } } + + /// Immutably borrows the wrapped value, returning an error if the value is + /// currently mutably borrowed. + /// + /// # Safety + /// + /// Unlike `RefCell::borrow`, this method is unsafe because it does not + /// return a `Ref`, thus leaving the borrow flag untouched. Mutably + /// borrowing the `RefCell` while the reference returned by this method + /// is alive is undefined behaviour. + /// + /// # Examples + /// + /// ``` + /// #![feature(borrow_state)] + /// use std::cell::RefCell; + /// + /// let c = RefCell::new(5); + /// + /// { + /// let m = c.borrow_mut(); + /// assert!(unsafe { c.try_borrow_unguarded() }.is_err()); + /// } + /// + /// { + /// let m = c.borrow(); + /// assert!(unsafe { c.try_borrow_unguarded() }.is_ok()); + /// } + /// ``` + #[unstable(feature = "borrow_state", issue = "27733")] + #[inline] + pub unsafe fn try_borrow_unguarded(&self) -> Result<&T, BorrowError> { + if !is_writing(self.borrow.get()) { + Ok(&*self.value.get()) + } else { + Err(BorrowError { _private: () }) + } + } } #[stable(feature = "rust1", since = "1.0.0")]