diff options
| author | Steven Fackler <sfackler@gmail.com> | 2014-04-08 22:54:06 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-04-10 15:21:59 -0700 |
| commit | b99482801fd09f33c70329bc72fc6efebd7cd3b5 (patch) | |
| tree | 09d9ccf58873c8b4c244a265b06b0ed08b9b6adf | |
| parent | 6e63b12f5f1c4974bcb90455b01146938f73f328 (diff) | |
| download | rust-b99482801fd09f33c70329bc72fc6efebd7cd3b5.tar.gz rust-b99482801fd09f33c70329bc72fc6efebd7cd3b5.zip | |
Stop using transmute_mut in RefCell
This is supposedly undefined behavior now that Unsafe exists, so we'll use Cell instead.
| -rw-r--r-- | src/libstd/cell.rs | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index 40c6c3ebccf..ec064f4f5ec 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -10,7 +10,6 @@ //! Types dealing with dynamic mutability -use cast; use clone::Clone; use cmp::Eq; use fmt; @@ -70,7 +69,7 @@ impl<T: Copy + fmt::Show> fmt::Show for Cell<T> { /// A mutable memory location with dynamically checked borrow rules pub struct RefCell<T> { value: Unsafe<T>, - borrow: BorrowFlag, + borrow: Cell<BorrowFlag>, nocopy: marker::NoCopy, noshare: marker::NoShare, } @@ -86,22 +85,18 @@ impl<T> RefCell<T> { pub fn new(value: T) -> RefCell<T> { RefCell { value: Unsafe::new(value), + borrow: Cell::new(UNUSED), nocopy: marker::NoCopy, noshare: marker::NoShare, - borrow: UNUSED, } } /// Consumes the `RefCell`, returning the wrapped value. pub fn unwrap(self) -> T { - assert!(self.borrow == UNUSED); + assert!(self.borrow.get() == UNUSED); unsafe{self.value.unwrap()} } - unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> { - cast::transmute_mut(self) - } - /// Attempts to immutably borrow the wrapped value. /// /// The borrow lasts until the returned `Ref` exits scope. Multiple @@ -109,10 +104,10 @@ impl<T> RefCell<T> { /// /// Returns `None` if the value is currently mutably borrowed. pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> { - match self.borrow { + match self.borrow.get() { WRITING => None, - _ => { - unsafe { self.as_mut().borrow += 1; } + borrow => { + self.borrow.set(borrow + 1); Some(Ref { parent: self }) } } @@ -140,11 +135,10 @@ impl<T> RefCell<T> { /// /// Returns `None` if the value is currently borrowed. pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> { - match self.borrow { - UNUSED => unsafe { - let mut_self = self.as_mut(); - mut_self.borrow = WRITING; - Some(RefMut { parent: mut_self }) + match self.borrow.get() { + UNUSED => { + self.borrow.set(WRITING); + Some(RefMut { parent: self }) }, _ => None } @@ -186,8 +180,9 @@ pub struct Ref<'b, T> { #[unsafe_destructor] impl<'b, T> Drop for Ref<'b, T> { fn drop(&mut self) { - assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED); - unsafe { self.parent.as_mut().borrow -= 1; } + let borrow = self.parent.borrow.get(); + assert!(borrow != WRITING && borrow != UNUSED); + self.parent.borrow.set(borrow - 1); } } @@ -200,14 +195,15 @@ impl<'b, T> Deref<T> for Ref<'b, T> { /// Wraps a mutable borrowed reference to a value in a `RefCell` box. pub struct RefMut<'b, T> { - parent: &'b mut RefCell<T> + parent: &'b RefCell<T> } #[unsafe_destructor] impl<'b, T> Drop for RefMut<'b, T> { fn drop(&mut self) { - assert!(self.parent.borrow == WRITING); - self.parent.borrow = UNUSED; + let borrow = self.parent.borrow.get(); + assert!(borrow == WRITING); + self.parent.borrow.set(UNUSED); } } |
