about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-05-15 18:06:22 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-05-15 19:18:09 -0400
commit4702667a62be3286828e2c43094cbfbcfd26ad2a (patch)
tree2951f5e2eaedde7a9df5a3e41007bb6e2edddaa5 /src/libstd
parent8a15333c06b8ba491e1654c3fca3fa21d21def9b (diff)
downloadrust-4702667a62be3286828e2c43094cbfbcfd26ad2a.tar.gz
rust-4702667a62be3286828e2c43094cbfbcfd26ad2a.zip
allow constructing Rc/RcMut from Const types too
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/rc.rs108
1 files changed, 66 insertions, 42 deletions
diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs
index cb0798f2a39..46f50eafec1 100644
--- a/src/libstd/rc.rs
+++ b/src/libstd/rc.rs
@@ -11,7 +11,11 @@
 /** Task-local reference counted smart pointers
 
 Task-local reference counted smart pointers are an alternative to managed boxes with deterministic
-destruction. They are restricted to containing `Owned` types in order to prevent cycles.
+destruction. They are restricted to containing types that are either `Owned` or `Const` (or both) to
+prevent cycles.
+
+Neither `Rc<T>` or `RcMut<T>` is ever `Owned` and `RcMut<T>` is never `Const`. If `T` is `Const`, a
+cycle cannot be created with `Rc<T>` because there is no way to modify it after creation.
 
 */
 
@@ -30,16 +34,26 @@ pub struct Rc<T> {
     priv ptr: *mut RcBox<T>,
 }
 
-pub impl<T: Owned> Rc<T> {
-    fn new(value: T) -> Rc<T> {
-        unsafe {
-            let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>;
-            assert!(!ptr::is_null(ptr));
-            intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1});
-            Rc{ptr: ptr}
-        }
+priv impl<T> Rc<T> {
+    unsafe fn new(value: T) -> Rc<T> {
+        let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>;
+        assert!(!ptr::is_null(ptr));
+        intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1});
+        Rc{ptr: ptr}
     }
+}
+
+// FIXME: #6516: should be a static method
+pub fn rc_from_owned<T: Owned>(value: T) -> Rc<T> {
+    unsafe { Rc::new(value) }
+}
+
+// FIXME: #6516: should be a static method
+pub fn rc_from_const<T: Const>(value: T) -> Rc<T> {
+    unsafe { Rc::new(value) }
+}
 
+pub impl<T> Rc<T> {
     #[inline(always)]
     fn borrow<'r>(&'r self) -> &'r T {
         unsafe { cast::copy_lifetime(self, &(*self.ptr).value) }
@@ -48,7 +62,7 @@ pub impl<T: Owned> Rc<T> {
 
 #[unsafe_destructor]
 #[cfg(not(stage0))]
-impl<T: Owned> Drop for Rc<T> {
+impl<T> Drop for Rc<T> {
     fn finalize(&self) {
         unsafe {
             (*self.ptr).count -= 1;
@@ -62,7 +76,7 @@ impl<T: Owned> Drop for Rc<T> {
 
 #[unsafe_destructor]
 #[cfg(stage0)]
-impl<T: Owned> Drop for Rc<T> {
+impl<T> Drop for Rc<T> {
     fn finalize(&self) {
         unsafe {
             (*self.ptr).count -= 1;
@@ -75,7 +89,7 @@ impl<T: Owned> Drop for Rc<T> {
 }
 
 
-impl<T: Owned> Clone for Rc<T> {
+impl<T> Clone for Rc<T> {
     /// Return a shallow copy of the reference counted pointer.
     #[inline]
     fn clone(&self) -> Rc<T> {
@@ -86,11 +100,11 @@ impl<T: Owned> Clone for Rc<T> {
     }
 }
 
-impl<T: Owned + DeepClone> DeepClone for Rc<T> {
+impl<T: DeepClone> DeepClone for Rc<T> {
     /// Return a deep copy of the reference counted pointer.
     #[inline]
     fn deep_clone(&self) -> Rc<T> {
-        Rc::new(self.borrow().deep_clone())
+        unsafe { Rc::new(self.borrow().deep_clone()) }
     }
 }
 
@@ -101,7 +115,7 @@ mod test_rc {
 
     #[test]
     fn test_clone() {
-        let x = Rc::new(Cell(5));
+        let x = rc_from_owned(Cell(5));
         let y = x.clone();
         do x.borrow().with_mut_ref |inner| {
             *inner = 20;
@@ -111,7 +125,7 @@ mod test_rc {
 
     #[test]
     fn test_deep_clone() {
-        let x = Rc::new(Cell(5));
+        let x = rc_from_owned(Cell(5));
         let y = x.deep_clone();
         do x.borrow().with_mut_ref |inner| {
             *inner = 20;
@@ -121,13 +135,13 @@ mod test_rc {
 
     #[test]
     fn test_simple() {
-        let x = Rc::new(5);
+        let x = rc_from_const(5);
         assert_eq!(*x.borrow(), 5);
     }
 
     #[test]
     fn test_simple_clone() {
-        let x = Rc::new(5);
+        let x = rc_from_const(5);
         let y = x.clone();
         assert_eq!(*x.borrow(), 5);
         assert_eq!(*y.borrow(), 5);
@@ -135,7 +149,7 @@ mod test_rc {
 
     #[test]
     fn test_destructor() {
-        let x = Rc::new(~5);
+        let x = rc_from_owned(~5);
         assert_eq!(**x.borrow(), 5);
     }
 }
@@ -167,16 +181,26 @@ pub struct RcMut<T> {
     priv ptr: *mut RcMutBox<T>,
 }
 
-pub impl<T: Owned> RcMut<T> {
-    fn new(value: T) -> RcMut<T> {
-        unsafe {
-            let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>;
-            assert!(!ptr::is_null(ptr));
-            intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing});
-            RcMut{ptr: ptr}
-        }
+priv impl<T> RcMut<T> {
+    unsafe fn new(value: T) -> RcMut<T> {
+        let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>;
+        assert!(!ptr::is_null(ptr));
+        intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing});
+        RcMut{ptr: ptr}
     }
+}
+
+// FIXME: #6516: should be a static method
+pub fn rc_mut_from_owned<T: Owned>(value: T) -> RcMut<T> {
+    unsafe { RcMut::new(value) }
+}
+
+// FIXME: #6516: should be a static method
+pub fn rc_mut_from_const<T: Const>(value: T) -> RcMut<T> {
+    unsafe { RcMut::new(value) }
+}
 
+pub impl<T> RcMut<T> {
     /// Fails if there is already a mutable borrow of the box
     #[inline]
     fn with_borrow<U>(&self, f: &fn(&T) -> U) -> U {
@@ -205,7 +229,7 @@ pub impl<T: Owned> RcMut<T> {
 
 #[unsafe_destructor]
 #[cfg(not(stage0))]
-impl<T: Owned> Drop for RcMut<T> {
+impl<T> Drop for RcMut<T> {
     fn finalize(&self) {
         unsafe {
             (*self.ptr).count -= 1;
@@ -219,7 +243,7 @@ impl<T: Owned> Drop for RcMut<T> {
 
 #[unsafe_destructor]
 #[cfg(stage0)]
-impl<T: Owned> Drop for RcMut<T> {
+impl<T> Drop for RcMut<T> {
     fn finalize(&self) {
         unsafe {
             (*self.ptr).count -= 1;
@@ -231,7 +255,7 @@ impl<T: Owned> Drop for RcMut<T> {
     }
 }
 
-impl<T: Owned> Clone for RcMut<T> {
+impl<T> Clone for RcMut<T> {
     /// Return a shallow copy of the reference counted pointer.
     #[inline]
     fn clone(&self) -> RcMut<T> {
@@ -242,13 +266,13 @@ impl<T: Owned> Clone for RcMut<T> {
     }
 }
 
-impl<T: Owned + DeepClone> DeepClone for RcMut<T> {
+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)
-            RcMut::new(x.deep_clone())
+            unsafe { RcMut::new(x.deep_clone()) }
         }
     }
 }
@@ -259,7 +283,7 @@ mod test_rc_mut {
 
     #[test]
     fn test_clone() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_owned(5);
         let y = x.clone();
         do x.with_mut_borrow |value| {
             *value = 20;
@@ -271,7 +295,7 @@ mod test_rc_mut {
 
     #[test]
     fn test_deep_clone() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_const(5);
         let y = x.deep_clone();
         do x.with_mut_borrow |value| {
             *value = 20;
@@ -283,7 +307,7 @@ mod test_rc_mut {
 
     #[test]
     fn borrow_many() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_owned(5);
         let y = x.clone();
 
         do x.with_borrow |a| {
@@ -299,7 +323,7 @@ mod test_rc_mut {
 
     #[test]
     fn modify() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_const(5);
         let y = x.clone();
 
         do y.with_mut_borrow |a| {
@@ -314,14 +338,14 @@ mod test_rc_mut {
 
     #[test]
     fn release_immutable() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_owned(5);
         do x.with_borrow |_| {}
         do x.with_mut_borrow |_| {}
     }
 
     #[test]
     fn release_mutable() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_const(5);
         do x.with_mut_borrow |_| {}
         do x.with_borrow |_| {}
     }
@@ -329,7 +353,7 @@ mod test_rc_mut {
     #[test]
     #[should_fail]
     fn frozen() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_owned(5);
         let y = x.clone();
 
         do x.with_borrow |_| {
@@ -341,7 +365,7 @@ mod test_rc_mut {
     #[test]
     #[should_fail]
     fn mutable_dupe() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_const(5);
         let y = x.clone();
 
         do x.with_mut_borrow |_| {
@@ -353,7 +377,7 @@ mod test_rc_mut {
     #[test]
     #[should_fail]
     fn mutable_freeze() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_owned(5);
         let y = x.clone();
 
         do x.with_mut_borrow |_| {
@@ -365,7 +389,7 @@ mod test_rc_mut {
     #[test]
     #[should_fail]
     fn restore_freeze() {
-        let x = RcMut::new(5);
+        let x = rc_mut_from_const(5);
         let y = x.clone();
 
         do x.with_borrow |_| {