diff options
| author | Steven Fackler <sfackler@gmail.com> | 2013-11-14 19:57:11 -0800 |
|---|---|---|
| committer | Steven Fackler <sfackler@gmail.com> | 2013-11-22 21:19:53 -0800 |
| commit | 7c9daa8ff71cb5896af9bb9a6ec8e15391e76b4e (patch) | |
| tree | 88befa3aa9a8b826fe2f813f9bb27be690323de4 | |
| parent | 0fade3a714f7a7f9bff5c11f9f37528d0ab168a1 (diff) | |
| download | rust-7c9daa8ff71cb5896af9bb9a6ec8e15391e76b4e.tar.gz rust-7c9daa8ff71cb5896af9bb9a6ec8e15391e76b4e.zip | |
Remove RcMut
Rc<Mut<T>> should be used instead
| -rw-r--r-- | src/libstd/rc.rs | 237 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-7013.rs | 15 | ||||
| -rw-r--r-- | src/test/compile-fail/rcmut-not-const-and-not-owned.rs | 9 |
3 files changed, 14 insertions, 247 deletions
diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index 9e83afa819c..c4ee2190ad8 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -14,10 +14,6 @@ The `Rc` type provides shared ownership of an immutable value. Destruction is de will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the overhead of atomic reference counting. -The `RcMut` type provides shared ownership of a mutable value. Since multiple owners prevent -inherited mutability, a dynamic freezing check is used to maintain the invariant that an `&mut` -reference is a unique handle and the type is marked as non-`Freeze`. - */ use ptr::RawPtr; @@ -151,236 +147,3 @@ mod test_rc { assert_eq!(**x.borrow(), 5); } } - -#[deriving(Eq)] -enum Borrow { - Mutable, - Immutable, - Nothing -} - -struct RcMutBox<T> { - value: T, - count: uint, - borrow: Borrow -} - -/// Mutable reference counted pointer type -#[no_send] -#[no_freeze] -#[unsafe_no_drop_flag] -pub struct RcMut<T> { - priv ptr: *mut RcMutBox<T>, -} - -impl<T: Freeze> RcMut<T> { - /// Construct a new mutable reference-counted box from a `Freeze` value - #[inline] - pub fn new(value: T) -> RcMut<T> { - unsafe { RcMut::new_unchecked(value) } - } -} - -impl<T: Send> RcMut<T> { - /// Construct a new mutable reference-counted box from a `Send` value - #[inline] - pub fn from_send(value: T) -> RcMut<T> { - unsafe { RcMut::new_unchecked(value) } - } -} - -impl<T> RcMut<T> { - /// Unsafety construct a new mutable reference-counted box from any value. - /// - /// It is possible to create cycles, which will leak, and may interact - /// poorly with managed pointers. - #[inline] - pub unsafe fn new_unchecked(value: T) -> RcMut<T> { - RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, borrow: Nothing})} - } -} - -impl<T> RcMut<T> { - /// Fails if there is already a mutable borrow of the box - #[inline] - pub fn with_borrow<U>(&self, f: |&T| -> U) -> U { - unsafe { - assert!((*self.ptr).borrow != Mutable); - let previous = (*self.ptr).borrow; - (*self.ptr).borrow = Immutable; - let res = f(&(*self.ptr).value); - (*self.ptr).borrow = previous; - res - } - } - - /// Fails if there is already a mutable or immutable borrow of the box - #[inline] - pub fn with_mut_borrow<U>(&self, f: |&mut T| -> U) -> U { - unsafe { - assert_eq!((*self.ptr).borrow, Nothing); - (*self.ptr).borrow = Mutable; - let res = f(&mut (*self.ptr).value); - (*self.ptr).borrow = Nothing; - res - } - } -} - -#[unsafe_destructor] -impl<T> Drop for RcMut<T> { - fn drop(&mut self) { - unsafe { - if self.ptr.is_not_null() { - (*self.ptr).count -= 1; - if (*self.ptr).count == 0 { - let _: ~RcMutBox<T> = transmute(self.ptr); - } - } - } - } -} - -impl<T> Clone for RcMut<T> { - /// Return a shallow copy of the reference counted pointer. - #[inline] - fn clone(&self) -> RcMut<T> { - unsafe { - (*self.ptr).count += 1; - RcMut{ptr: self.ptr} - } - } -} - -impl<T: DeepClone> DeepClone for RcMut<T> { - /// Return a deep copy of the reference counted pointer. - #[inline] - fn deep_clone(&self) -> RcMut<T> { - do self.with_borrow |x| { - // FIXME: #6497: should avoid freeze (slow) - unsafe { RcMut::new_unchecked(x.deep_clone()) } - } - } -} - -#[cfg(test)] -mod test_rc_mut { - use super::*; - - #[test] - fn test_clone() { - let x = RcMut::from_send(5); - let y = x.clone(); - do x.with_mut_borrow |value| { - *value = 20; - } - do y.with_borrow |value| { - assert_eq!(*value, 20); - } - } - - #[test] - fn test_deep_clone() { - let x = RcMut::new(5); - let y = x.deep_clone(); - do x.with_mut_borrow |value| { - *value = 20; - } - do y.with_borrow |value| { - assert_eq!(*value, 5); - } - } - - #[test] - fn borrow_many() { - let x = RcMut::from_send(5); - let y = x.clone(); - - do x.with_borrow |a| { - assert_eq!(*a, 5); - do y.with_borrow |b| { - assert_eq!(*b, 5); - do x.with_borrow |c| { - assert_eq!(*c, 5); - } - } - } - } - - #[test] - fn modify() { - let x = RcMut::new(5); - let y = x.clone(); - - do y.with_mut_borrow |a| { - assert_eq!(*a, 5); - *a = 6; - } - - do x.with_borrow |a| { - assert_eq!(*a, 6); - } - } - - #[test] - fn release_immutable() { - let x = RcMut::from_send(5); - do x.with_borrow |_| {} - do x.with_mut_borrow |_| {} - } - - #[test] - fn release_mutable() { - let x = RcMut::new(5); - do x.with_mut_borrow |_| {} - do x.with_borrow |_| {} - } - - #[test] - #[should_fail] - fn frozen() { - let x = RcMut::from_send(5); - let y = x.clone(); - - do x.with_borrow |_| { - do y.with_mut_borrow |_| { - } - } - } - - #[test] - #[should_fail] - fn mutable_dupe() { - let x = RcMut::new(5); - let y = x.clone(); - - do x.with_mut_borrow |_| { - do y.with_mut_borrow |_| { - } - } - } - - #[test] - #[should_fail] - fn mutable_freeze() { - let x = RcMut::from_send(5); - let y = x.clone(); - - do x.with_mut_borrow |_| { - do y.with_borrow |_| { - } - } - } - - #[test] - #[should_fail] - fn restore_freeze() { - let x = RcMut::new(5); - let y = x.clone(); - - do x.with_borrow |_| { - do x.with_borrow |_| {} - do y.with_mut_borrow |_| {} - } - } -} diff --git a/src/test/compile-fail/issue-7013.rs b/src/test/compile-fail/issue-7013.rs index 5f39aac19af..feea0765ec2 100644 --- a/src/test/compile-fail/issue-7013.rs +++ b/src/test/compile-fail/issue-7013.rs @@ -8,21 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::rc::RcMut; +use std::rc::Rc; +use std::mutable::Mut; trait Foo { - fn set(&mut self, v: RcMut<A>); + fn set(&mut self, v: Rc<Mut<A>>); } struct B { - v: Option<RcMut<A>> + v: Option<Rc<Mut<A>>> } impl Foo for B { - fn set(&mut self, v: RcMut<A>) + fn set(&mut self, v: Rc<Mut<A>>) { self.v = Some(v); } @@ -36,7 +37,9 @@ struct A fn main() { let a = A {v: ~B{v: None} as ~Foo}; //~ ERROR cannot pack type `~B`, which does not fulfill `Send` - let v = RcMut::new(a); //~ ERROR instantiating a type parameter with an incompatible type + let v = Rc::from_send(Mut::new(a)); let w = v.clone(); - v.with_mut_borrow(|p| {p.v.set(w.clone());}) + let b = v.borrow(); + let mut b = b.borrow_mut(); + b.get().v.set(w.clone()); } diff --git a/src/test/compile-fail/rcmut-not-const-and-not-owned.rs b/src/test/compile-fail/rcmut-not-const-and-not-owned.rs index fce1f592c62..981cec6f0ba 100644 --- a/src/test/compile-fail/rcmut-not-const-and-not-owned.rs +++ b/src/test/compile-fail/rcmut-not-const-and-not-owned.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::rc::RcMut; +use std::mutable::Mut; +use std::rc::Rc; fn o<T: Send>(_: &T) {} fn c<T: Freeze>(_: &T) {} fn main() { - let x = RcMut::from_send(0); - o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut<int>`, which does not fulfill `Send` - c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut<int>`, which does not fulfill `Freeze` + let x = Rc::from_send(Mut::new(0)); + o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::mutable::Mut<int>>`, which does not fulfill `Send` + c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc<std::mutable::Mut<int>>`, which does not fulfill `Freeze` } |
