@@ -277,12 +277,9 @@ impl<T> RefCell<T> {
277
277
/// Returns `None` if the value is currently mutably borrowed.
278
278
#[ unstable = "may be renamed, depending on global conventions" ]
279
279
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 ,
286
283
}
287
284
}
288
285
@@ -310,12 +307,9 @@ impl<T> RefCell<T> {
310
307
/// Returns `None` if the value is currently borrowed.
311
308
#[ unstable = "may be renamed, depending on global conventions" ]
312
309
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 ,
319
313
}
320
314
}
321
315
@@ -368,29 +362,56 @@ impl<T: PartialEq> PartialEq for RefCell<T> {
368
362
}
369
363
}
370
364
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
+ }
377
379
}
378
380
379
381
#[ unsafe_destructor]
380
- #[ unstable]
381
- impl < ' b , T > Drop for Ref < ' b , T > {
382
+ impl < ' b > Drop for BorrowRef < ' b > {
382
383
fn drop ( & mut self ) {
383
- let borrow = self . _parent . borrow . get ( ) ;
384
+ let borrow = self . _borrow . get ( ) ;
384
385
debug_assert ! ( borrow != WRITING && borrow != UNUSED ) ;
385
- self . _parent . borrow . set ( borrow - 1 ) ;
386
+ self . _borrow . set ( borrow - 1 ) ;
386
387
}
387
388
}
388
389
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
+
389
410
#[ unstable = "waiting for `Deref` to become stable" ]
390
411
impl < ' b , T > Deref < T > for Ref < ' b , T > {
391
412
#[ inline]
392
413
fn deref < ' a > ( & ' a self ) -> & ' a T {
393
- unsafe { & * self . _parent . value . get ( ) }
414
+ self . _value
394
415
}
395
416
}
396
417
@@ -401,49 +422,60 @@ impl<'b, T> Deref<T> for Ref<'b, T> {
401
422
/// A `Clone` implementation would interfere with the widespread
402
423
/// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
403
424
#[ 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 > {
411
426
Ref {
412
- _parent : orig. _parent ,
427
+ _value : orig. _value ,
428
+ _borrow : orig. _borrow . clone ( ) ,
413
429
}
414
430
}
415
431
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 > ,
422
434
}
423
435
424
436
#[ unsafe_destructor]
425
- #[ unstable]
426
- impl < ' b , T > Drop for RefMut < ' b , T > {
437
+ impl < ' b > Drop for BorrowRefMut < ' b > {
427
438
fn drop ( & mut self ) {
428
- let borrow = self . _parent . borrow . get ( ) ;
439
+ let borrow = self . _borrow . get ( ) ;
429
440
debug_assert ! ( borrow == WRITING ) ;
430
- self . _parent . borrow . set ( UNUSED ) ;
441
+ self . _borrow . set ( UNUSED ) ;
431
442
}
432
443
}
433
444
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
+
434
466
#[ unstable = "waiting for `Deref` to become stable" ]
435
467
impl < ' b , T > Deref < T > for RefMut < ' b , T > {
436
468
#[ inline]
437
469
fn deref < ' a > ( & ' a self ) -> & ' a T {
438
- unsafe { & * self . _parent . value . get ( ) }
470
+ self . _value
439
471
}
440
472
}
441
473
442
474
#[ unstable = "waiting for `DerefMut` to become stable" ]
443
475
impl < ' b , T > DerefMut < T > for RefMut < ' b , T > {
444
476
#[ inline]
445
477
fn deref_mut < ' a > ( & ' a mut self ) -> & ' a mut T {
446
- unsafe { & mut * self . _parent . value . get ( ) }
478
+ self . _value
447
479
}
448
480
}
449
481
0 commit comments