From 7c9daa8ff71cb5896af9bb9a6ec8e15391e76b4e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 14 Nov 2013 19:57:11 -0800 Subject: [PATCH] Remove RcMut Rc> should be used instead --- src/libstd/rc.rs | 237 ------------------ src/test/compile-fail/issue-7013.rs | 15 +- .../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 { - value: T, - count: uint, - borrow: Borrow -} - -/// Mutable reference counted pointer type -#[no_send] -#[no_freeze] -#[unsafe_no_drop_flag] -pub struct RcMut { - priv ptr: *mut RcMutBox, -} - -impl RcMut { - /// Construct a new mutable reference-counted box from a `Freeze` value - #[inline] - pub fn new(value: T) -> RcMut { - unsafe { RcMut::new_unchecked(value) } - } -} - -impl RcMut { - /// Construct a new mutable reference-counted box from a `Send` value - #[inline] - pub fn from_send(value: T) -> RcMut { - unsafe { RcMut::new_unchecked(value) } - } -} - -impl RcMut { - /// 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 { - RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, borrow: Nothing})} - } -} - -impl RcMut { - /// Fails if there is already a mutable borrow of the box - #[inline] - pub fn with_borrow(&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(&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 Drop for RcMut { - fn drop(&mut self) { - unsafe { - if self.ptr.is_not_null() { - (*self.ptr).count -= 1; - if (*self.ptr).count == 0 { - let _: ~RcMutBox = transmute(self.ptr); - } - } - } - } -} - -impl Clone for RcMut { - /// Return a shallow copy of the reference counted pointer. - #[inline] - fn clone(&self) -> RcMut { - unsafe { - (*self.ptr).count += 1; - RcMut{ptr: self.ptr} - } - } -} - -impl DeepClone for RcMut { - /// Return a deep copy of the reference counted pointer. - #[inline] - fn deep_clone(&self) -> RcMut { - 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); + fn set(&mut self, v: Rc>); } struct B { - v: Option> + v: Option>> } impl Foo for B { - fn set(&mut self, v: RcMut) + fn set(&mut self, v: Rc>) { 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) {} fn c(_: &T) {} fn main() { - let x = RcMut::from_send(0); - o(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut`, which does not fulfill `Send` - c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::RcMut`, 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>`, which does not fulfill `Send` + c(&x); //~ ERROR instantiating a type parameter with an incompatible type `std::rc::Rc>`, which does not fulfill `Freeze` }