diff --git a/src/doc/unstable-book/src/library-features/borrow-state.md b/src/doc/unstable-book/src/library-features/borrow-state.md new file mode 100644 index 0000000000000..304b8dffe9867 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/borrow-state.md @@ -0,0 +1,7 @@ +# `borrow_state` + +The tracking issue for this feature is: [#27733] + +[#27733]: /~https://github.com/rust-lang/rust/issues/27733 + +------------------------ diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 80dd51acc9eee..5325b339151dc 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -955,6 +955,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")]