@@ -266,6 +266,18 @@ pub struct RefCell<T> {
266266 borrow : Cell < BorrowFlag > ,
267267}
268268
269+ /// An enumeration of values returned from the `state` method on a `RefCell<T>`.
270+ #[ derive( Copy , Clone , PartialEq ) ]
271+ #[ unstable( feature = "std_misc" ) ]
272+ pub enum BorrowState {
273+ /// The cell is currently being read, there is at least one active `borrow`.
274+ Reading ,
275+ /// The cell is currently being written to, there is an active `borrow_mut`.
276+ Writing ,
277+ /// There are no outstanding borrows on this cell.
278+ Unused ,
279+ }
280+
269281// Values [1, MAX-1] represent the number of `Ref` active
270282// (will not outgrow its range since `uint` is the size of the address space)
271283type BorrowFlag = uint ;
@@ -310,13 +322,28 @@ impl<T> RefCell<T> {
310322 unsafe { self . value . into_inner ( ) }
311323 }
312324
325+ /// Query the current state of this `RefCell`
326+ ///
327+ /// The returned value can be dispatched on to determine if a call to
328+ /// `borrow` or `borrow_mut` would succeed.
329+ #[ unstable( feature = "std_misc" ) ]
330+ pub fn borrow_state ( & self ) -> BorrowState {
331+ match self . borrow . get ( ) {
332+ WRITING => BorrowState :: Writing ,
333+ UNUSED => BorrowState :: Unused ,
334+ _ => BorrowState :: Reading ,
335+ }
336+ }
337+
313338 /// Attempts to immutably borrow the wrapped value.
314339 ///
315340 /// The borrow lasts until the returned `Ref` exits scope. Multiple
316341 /// immutable borrows can be taken out at the same time.
317342 ///
318343 /// Returns `None` if the value is currently mutably borrowed.
319344 #[ unstable( feature = "core" , reason = "may be renamed or removed" ) ]
345+ #[ deprecated( since = "1.0.0" ,
346+ reason = "dispatch on `cell.borrow_state()` instead" ) ]
320347 pub fn try_borrow < ' a > ( & ' a self ) -> Option < Ref < ' a , T > > {
321348 match BorrowRef :: new ( & self . borrow ) {
322349 Some ( b) => Some ( Ref { _value : unsafe { & * self . value . get ( ) } , _borrow : b } ) ,
@@ -326,8 +353,8 @@ impl<T> RefCell<T> {
326353
327354 /// Immutably borrows the wrapped value.
328355 ///
329- /// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be
330- /// taken out at the same time.
356+ /// The borrow lasts until the returned `Ref` exits scope. Multiple
357+ /// immutable borrows can be taken out at the same time.
331358 ///
332359 /// # Panics
333360 ///
@@ -361,9 +388,12 @@ impl<T> RefCell<T> {
361388 /// ```
362389 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
363390 pub fn borrow < ' a > ( & ' a self ) -> Ref < ' a , T > {
364- match self . try_borrow ( ) {
365- Some ( ptr) => ptr,
366- None => panic ! ( "RefCell<T> already mutably borrowed" )
391+ match BorrowRef :: new ( & self . borrow ) {
392+ Some ( b) => Ref {
393+ _value : unsafe { & * self . value . get ( ) } ,
394+ _borrow : b,
395+ } ,
396+ None => panic ! ( "RefCell<T> already mutably borrowed" ) ,
367397 }
368398 }
369399
@@ -374,6 +404,8 @@ impl<T> RefCell<T> {
374404 ///
375405 /// Returns `None` if the value is currently borrowed.
376406 #[ unstable( feature = "core" , reason = "may be renamed or removed" ) ]
407+ #[ deprecated( since = "1.0.0" ,
408+ reason = "dispatch on `cell.borrow_state()` instead" ) ]
377409 pub fn try_borrow_mut < ' a > ( & ' a self ) -> Option < RefMut < ' a , T > > {
378410 match BorrowRefMut :: new ( & self . borrow ) {
379411 Some ( b) => Some ( RefMut { _value : unsafe { & mut * self . value . get ( ) } , _borrow : b } ) ,
@@ -383,8 +415,8 @@ impl<T> RefCell<T> {
383415
384416 /// Mutably borrows the wrapped value.
385417 ///
386- /// The borrow lasts until the returned `RefMut` exits scope. The value cannot be borrowed
387- /// while this borrow is active.
418+ /// The borrow lasts until the returned `RefMut` exits scope. The value
419+ /// cannot be borrowed while this borrow is active.
388420 ///
389421 /// # Panics
390422 ///
@@ -417,9 +449,12 @@ impl<T> RefCell<T> {
417449 /// ```
418450 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
419451 pub fn borrow_mut < ' a > ( & ' a self ) -> RefMut < ' a , T > {
420- match self . try_borrow_mut ( ) {
421- Some ( ptr) => ptr,
422- None => panic ! ( "RefCell<T> already borrowed" )
452+ match BorrowRefMut :: new ( & self . borrow ) {
453+ Some ( b) => RefMut {
454+ _value : unsafe { & mut * self . value . get ( ) } ,
455+ _borrow : b,
456+ } ,
457+ None => panic ! ( "RefCell<T> already borrowed" ) ,
423458 }
424459 }
425460
0 commit comments