@@ -277,12 +277,9 @@ impl<T> RefCell<T> {
277277 /// Returns `None` if the value is currently mutably borrowed.
278278 #[ unstable = "may be renamed, depending on global conventions" ]
279279 pub fn try_borrow < ' a > ( & ' a self ) -> Option < Ref < ' a , T > > {
280- match self . borrow . get ( ) {
281- WRITING => None ,
282- borrow => {
283- self . borrow . set ( borrow + 1 ) ;
284- Some ( Ref { _parent : self } )
285- }
280+ match BorrowRef :: new ( & self . borrow ) {
281+ Some ( b) => Some ( Ref { _value : unsafe { & * self . value . get ( ) } , _borrow : b } ) ,
282+ None => None ,
286283 }
287284 }
288285
@@ -310,12 +307,9 @@ impl<T> RefCell<T> {
310307 /// Returns `None` if the value is currently borrowed.
311308 #[ unstable = "may be renamed, depending on global conventions" ]
312309 pub fn try_borrow_mut < ' a > ( & ' a self ) -> Option < RefMut < ' a , T > > {
313- match self . borrow . get ( ) {
314- UNUSED => {
315- self . borrow . set ( WRITING ) ;
316- Some ( RefMut { _parent : self } )
317- } ,
318- _ => None
310+ match BorrowRefMut :: new ( & self . borrow ) {
311+ Some ( b) => Some ( RefMut { _value : unsafe { & mut * self . value . get ( ) } , _borrow : b } ) ,
312+ None => None ,
319313 }
320314 }
321315
@@ -368,29 +362,56 @@ impl<T: PartialEq> PartialEq for RefCell<T> {
368362 }
369363}
370364
371- /// Wraps a borrowed reference to a value in a `RefCell` box.
372- #[ unstable]
373- pub struct Ref < ' b , T : ' b > {
374- // FIXME #12808: strange name to try to avoid interfering with
375- // field accesses of the contained type via Deref
376- _parent : & ' b RefCell < T >
365+ struct BorrowRef < ' b > {
366+ _borrow : & ' b Cell < BorrowFlag > ,
367+ }
368+
369+ impl < ' b > BorrowRef < ' b > {
370+ fn new ( borrow : & ' b Cell < BorrowFlag > ) -> Option < BorrowRef < ' b > > {
371+ match borrow. get ( ) {
372+ WRITING => None ,
373+ b => {
374+ borrow. set ( b + 1 ) ;
375+ Some ( BorrowRef { _borrow : borrow } )
376+ } ,
377+ }
378+ }
377379}
378380
379381#[ unsafe_destructor]
380- #[ unstable]
381- impl < ' b , T > Drop for Ref < ' b , T > {
382+ impl < ' b > Drop for BorrowRef < ' b > {
382383 fn drop ( & mut self ) {
383- let borrow = self . _parent . borrow . get ( ) ;
384+ let borrow = self . _borrow . get ( ) ;
384385 debug_assert ! ( borrow != WRITING && borrow != UNUSED ) ;
385- self . _parent . borrow . set ( borrow - 1 ) ;
386+ self . _borrow . set ( borrow - 1 ) ;
386387 }
387388}
388389
390+ impl < ' b > Clone for BorrowRef < ' b > {
391+ fn clone ( & self ) -> BorrowRef < ' b > {
392+ // Since this Ref exists, we know the borrow flag
393+ // is not set to WRITING.
394+ let borrow = self . _borrow . get ( ) ;
395+ debug_assert ! ( borrow != WRITING && borrow != UNUSED ) ;
396+ self . _borrow . set ( borrow + 1 ) ;
397+ BorrowRef { _borrow : self . _borrow }
398+ }
399+ }
400+
401+ /// Wraps a borrowed reference to a value in a `RefCell` box.
402+ #[ unstable]
403+ pub struct Ref < ' b , T : ' b > {
404+ // FIXME #12808: strange name to try to avoid interfering with
405+ // field accesses of the contained type via Deref
406+ _value : & ' b T ,
407+ _borrow : BorrowRef < ' b > ,
408+ }
409+
389410#[ unstable = "waiting for `Deref` to become stable" ]
390411impl < ' b , T > Deref < T > for Ref < ' b , T > {
391412 #[ inline]
392413 fn deref < ' a > ( & ' a self ) -> & ' a T {
393- unsafe { & * self . _parent . value . get ( ) }
414+ self . _value
394415 }
395416}
396417
@@ -401,49 +422,60 @@ impl<'b, T> Deref<T> for Ref<'b, T> {
401422/// A `Clone` implementation would interfere with the widespread
402423/// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
403424#[ experimental = "likely to be moved to a method, pending language changes" ]
404- pub fn clone_ref < ' b , T > ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
405- // Since this Ref exists, we know the borrow flag
406- // is not set to WRITING.
407- let borrow = orig. _parent . borrow . get ( ) ;
408- debug_assert ! ( borrow != WRITING && borrow != UNUSED ) ;
409- orig. _parent . borrow . set ( borrow + 1 ) ;
410-
425+ pub fn clone_ref < ' b , T : Clone > ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
411426 Ref {
412- _parent : orig. _parent ,
427+ _value : orig. _value ,
428+ _borrow : orig. _borrow . clone ( ) ,
413429 }
414430}
415431
416- /// Wraps a mutable borrowed reference to a value in a `RefCell` box.
417- #[ unstable]
418- pub struct RefMut < ' b , T : ' b > {
419- // FIXME #12808: strange name to try to avoid interfering with
420- // field accesses of the contained type via Deref
421- _parent : & ' b RefCell < T >
432+ struct BorrowRefMut < ' b > {
433+ _borrow : & ' b Cell < BorrowFlag > ,
422434}
423435
424436#[ unsafe_destructor]
425- #[ unstable]
426- impl < ' b , T > Drop for RefMut < ' b , T > {
437+ impl < ' b > Drop for BorrowRefMut < ' b > {
427438 fn drop ( & mut self ) {
428- let borrow = self . _parent . borrow . get ( ) ;
439+ let borrow = self . _borrow . get ( ) ;
429440 debug_assert ! ( borrow == WRITING ) ;
430- self . _parent . borrow . set ( UNUSED ) ;
441+ self . _borrow . set ( UNUSED ) ;
431442 }
432443}
433444
445+ impl < ' b > BorrowRefMut < ' b > {
446+ fn new ( borrow : & ' b Cell < BorrowFlag > ) -> Option < BorrowRefMut < ' b > > {
447+ match borrow. get ( ) {
448+ UNUSED => {
449+ borrow. set ( WRITING ) ;
450+ Some ( BorrowRefMut { _borrow : borrow } )
451+ } ,
452+ _ => None ,
453+ }
454+ }
455+ }
456+
457+ /// Wraps a mutable borrowed reference to a value in a `RefCell` box.
458+ #[ unstable]
459+ pub struct RefMut < ' b , T : ' b > {
460+ // FIXME #12808: strange name to try to avoid interfering with
461+ // field accesses of the contained type via Deref
462+ _value : & ' b mut T ,
463+ _borrow : BorrowRefMut < ' b > ,
464+ }
465+
434466#[ unstable = "waiting for `Deref` to become stable" ]
435467impl < ' b , T > Deref < T > for RefMut < ' b , T > {
436468 #[ inline]
437469 fn deref < ' a > ( & ' a self ) -> & ' a T {
438- unsafe { & * self . _parent . value . get ( ) }
470+ self . _value
439471 }
440472}
441473
442474#[ unstable = "waiting for `DerefMut` to become stable" ]
443475impl < ' b , T > DerefMut < T > for RefMut < ' b , T > {
444476 #[ inline]
445477 fn deref_mut < ' a > ( & ' a mut self ) -> & ' a mut T {
446- unsafe { & mut * self . _parent . value . get ( ) }
478+ self . _value
447479 }
448480}
449481
0 commit comments