Skip to content

Commit 5048953

Browse files
committed
Simplify RefCell code a bit, make deref a no-op.
1 parent fb52e69 commit 5048953

File tree

1 file changed

+75
-43
lines changed

1 file changed

+75
-43
lines changed

src/libcore/cell.rs

+75-43
Original file line numberDiff line numberDiff line change
@@ -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"]
390411
impl<'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"]
435467
impl<'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"]
443475
impl<'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

Comments
 (0)