From 8f86fa3b31ec80020c30b70d1d04987481f89e4c Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 24 Jul 2013 14:11:49 +0200 Subject: [PATCH] rc: Use ~T for allocation Simplify Rc/RcMut by using ~T when allocating a reference counted box. --- src/libextra/rc.rs | 90 +++++++++---------- .../rcmut-not-const-and-not-owned.rs | 2 +- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/libextra/rc.rs b/src/libextra/rc.rs index 8d6b146e142..04d6b8ebca5 100644 --- a/src/libextra/rc.rs +++ b/src/libextra/rc.rs @@ -23,11 +23,17 @@ use std::cast; -use std::libc::{c_void, size_t, malloc, free}; use std::ptr; -use std::sys; use std::unstable::intrinsics; +// Convert ~T into *mut T without dropping it +#[inline] +unsafe fn owned_to_raw(mut box: ~T) -> *mut T { + let ptr = ptr::to_mut_unsafe_ptr(box); + intrinsics::forget(box); + ptr +} + struct RcBox { value: T, count: uint @@ -42,21 +48,20 @@ pub struct Rc { impl Rc { unsafe fn new(value: T) -> Rc { - let ptr = malloc(sys::size_of::>() as size_t) as *mut RcBox; - assert!(!ptr::is_null(ptr)); - intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1}); - Rc{ptr: ptr} + Rc{ptr: owned_to_raw(~RcBox{value: value, count: 1})} } } -// FIXME: #6516: should be a static method -pub fn rc_from_owned(value: T) -> Rc { - unsafe { Rc::new(value) } +impl Rc { + pub fn from_owned(value: T) -> Rc { + unsafe { Rc::new(value) } + } } -// FIXME: #6516: should be a static method -pub fn rc_from_const(value: T) -> Rc { - unsafe { Rc::new(value) } +impl Rc { + pub fn from_const(value: T) -> Rc { + unsafe { Rc::new(value) } + } } impl Rc { @@ -73,8 +78,7 @@ fn drop(&self) { if self.ptr.is_not_null() { (*self.ptr).count -= 1; if (*self.ptr).count == 0 { - ptr::read_ptr(self.ptr); - free(self.ptr as *c_void) + let _: ~T = cast::transmute(self.ptr); } } } @@ -107,7 +111,7 @@ mod test_rc { #[test] fn test_clone() { - let x = rc_from_owned(Cell::new(5)); + let x = Rc::from_owned(Cell::new(5)); let y = x.clone(); do x.borrow().with_mut_ref |inner| { *inner = 20; @@ -117,7 +121,7 @@ fn test_clone() { #[test] fn test_deep_clone() { - let x = rc_from_owned(Cell::new(5)); + let x = Rc::from_owned(Cell::new(5)); let y = x.deep_clone(); do x.borrow().with_mut_ref |inner| { *inner = 20; @@ -127,13 +131,13 @@ fn test_deep_clone() { #[test] fn test_simple() { - let x = rc_from_const(5); + let x = Rc::from_const(5); assert_eq!(*x.borrow(), 5); } #[test] fn test_simple_clone() { - let x = rc_from_const(5); + let x = Rc::from_const(5); let y = x.clone(); assert_eq!(*x.borrow(), 5); assert_eq!(*y.borrow(), 5); @@ -141,17 +145,11 @@ fn test_simple_clone() { #[test] fn test_destructor() { - let x = rc_from_owned(~5); + let x = Rc::from_owned(~5); assert_eq!(**x.borrow(), 5); } } -#[abi = "rust-intrinsic"] -extern "rust-intrinsic" { - fn init() -> T; - fn uninit() -> T; -} - #[deriving(Eq)] enum Borrow { Mutable, @@ -175,21 +173,20 @@ pub struct RcMut { impl RcMut { unsafe fn new(value: T) -> RcMut { - let ptr = malloc(sys::size_of::>() as size_t) as *mut RcMutBox; - assert!(!ptr::is_null(ptr)); - intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing}); - RcMut{ptr: ptr} + RcMut{ptr: owned_to_raw(~RcMutBox{value: value, count: 1, borrow: Nothing})} } } -// FIXME: #6516: should be a static method -pub fn rc_mut_from_owned(value: T) -> RcMut { - unsafe { RcMut::new(value) } +impl RcMut { + pub fn from_owned(value: T) -> RcMut { + unsafe { RcMut::new(value) } + } } -// FIXME: #6516: should be a static method -pub fn rc_mut_from_const(value: T) -> RcMut { - unsafe { RcMut::new(value) } +impl RcMut { + pub fn from_const(value: T) -> RcMut { + unsafe { RcMut::new(value) } + } } impl RcMut { @@ -226,8 +223,7 @@ fn drop(&self) { if self.ptr.is_not_null() { (*self.ptr).count -= 1; if (*self.ptr).count == 0 { - ptr::replace_ptr(self.ptr, uninit()); - free(self.ptr as *c_void) + let _: ~T = cast::transmute(self.ptr); } } } @@ -262,7 +258,7 @@ mod test_rc_mut { #[test] fn test_clone() { - let x = rc_mut_from_owned(5); + let x = RcMut::from_owned(5); let y = x.clone(); do x.with_mut_borrow |value| { *value = 20; @@ -274,7 +270,7 @@ fn test_clone() { #[test] fn test_deep_clone() { - let x = rc_mut_from_const(5); + let x = RcMut::from_const(5); let y = x.deep_clone(); do x.with_mut_borrow |value| { *value = 20; @@ -286,7 +282,7 @@ fn test_deep_clone() { #[test] fn borrow_many() { - let x = rc_mut_from_owned(5); + let x = RcMut::from_owned(5); let y = x.clone(); do x.with_borrow |a| { @@ -302,7 +298,7 @@ fn borrow_many() { #[test] fn modify() { - let x = rc_mut_from_const(5); + let x = RcMut::from_const(5); let y = x.clone(); do y.with_mut_borrow |a| { @@ -317,14 +313,14 @@ fn modify() { #[test] fn release_immutable() { - let x = rc_mut_from_owned(5); + let x = RcMut::from_owned(5); do x.with_borrow |_| {} do x.with_mut_borrow |_| {} } #[test] fn release_mutable() { - let x = rc_mut_from_const(5); + let x = RcMut::from_const(5); do x.with_mut_borrow |_| {} do x.with_borrow |_| {} } @@ -332,7 +328,7 @@ fn release_mutable() { #[test] #[should_fail] fn frozen() { - let x = rc_mut_from_owned(5); + let x = RcMut::from_owned(5); let y = x.clone(); do x.with_borrow |_| { @@ -344,7 +340,7 @@ fn frozen() { #[test] #[should_fail] fn mutable_dupe() { - let x = rc_mut_from_const(5); + let x = RcMut::from_const(5); let y = x.clone(); do x.with_mut_borrow |_| { @@ -356,7 +352,7 @@ fn mutable_dupe() { #[test] #[should_fail] fn mutable_freeze() { - let x = rc_mut_from_owned(5); + let x = RcMut::from_owned(5); let y = x.clone(); do x.with_mut_borrow |_| { @@ -368,7 +364,7 @@ fn mutable_freeze() { #[test] #[should_fail] fn restore_freeze() { - let x = rc_mut_from_const(5); + let x = RcMut::from_const(5); let y = x.clone(); do x.with_borrow |_| { 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 45cb137b084..c27debdbc7f 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 @@ -14,7 +14,7 @@ fn o(_: &T) {} fn c(_: &T) {} fn main() { - let x = extra::rc::rc_mut_from_owned(0); + let x = extra::rc::RcMut::from_owned(0); o(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut`, which does not fulfill `Send` c(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut`, which does not fulfill `Freeze` } -- 2.44.0