Remove RcMut
Rc<Mut<T>> should be used instead
This commit is contained in:
parent
0fade3a714
commit
7c9daa8ff7
237
src/libstd/rc.rs
237
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 |_| {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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`
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user