about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorLuqman Aden <laden@csclub.uwaterloo.ca>2014-12-04 12:59:28 -0500
committerLuqman Aden <laden@csclub.uwaterloo.ca>2014-12-28 19:40:47 -0500
commit0d48f76224371e884496182f6cfb3e2dad7690a2 (patch)
treece4bb26e8cc0a3cf59b0cf987abaa8ca678c1f6b /src/liballoc
parentbb4473774866a1a9a3965a62db3298f1be874418 (diff)
downloadrust-0d48f76224371e884496182f6cfb3e2dad7690a2.tar.gz
rust-0d48f76224371e884496182f6cfb3e2dad7690a2.zip
liballoc: Use NonZero in Rc.
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/rc.rs44
1 files changed, 29 insertions, 15 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index dfa55848c90..41efa0468ac 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -153,8 +153,7 @@ use core::mem::{transmute, min_align_of, size_of, forget};
 use core::ops::{Deref, Drop};
 use core::option::Option;
 use core::option::Option::{Some, None};
-use core::ptr;
-use core::ptr::RawPtr;
+use core::ptr::{mod, NonZero, RawPtr};
 use core::result::Result;
 use core::result::Result::{Ok, Err};
 
@@ -174,7 +173,7 @@ struct RcBox<T> {
 pub struct Rc<T> {
     // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
     // type via Deref
-    _ptr: *mut RcBox<T>,
+    _ptr: NonZero<*mut RcBox<T>>,
     _nosend: marker::NoSend,
     _noshare: marker::NoSync
 }
@@ -196,11 +195,11 @@ impl<T> Rc<T> {
                 // there is an implicit weak pointer owned by all the strong pointers, which
                 // ensures that the weak destructor never frees the allocation while the strong
                 // destructor is running, even if the weak pointer is stored inside the strong one.
-                _ptr: transmute(box RcBox {
+                _ptr: NonZero(transmute(box RcBox {
                     value: value,
                     strong: Cell::new(1),
                     weak: Cell::new(1)
-                }),
+                })),
                 _nosend: marker::NoSend,
                 _noshare: marker::NoSync
             }
@@ -281,7 +280,8 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
             let val = ptr::read(&*rc); // copy the contained object
             // destruct the box and skip our Drop
             // we can ignore the refcounts because we know we're unique
-            deallocate(rc._ptr as *mut u8, size_of::<RcBox<T>>(),
+            let NonZero(ptr) = rc._ptr;
+            deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
                         min_align_of::<RcBox<T>>());
             forget(rc);
             Ok(val)
@@ -311,7 +311,10 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
 #[experimental]
 pub fn get_mut<'a, T>(rc: &'a mut Rc<T>) -> Option<&'a mut T> {
     if is_unique(rc) {
-        let inner = unsafe { &mut *rc._ptr };
+        let inner = unsafe {
+            let NonZero(ptr) = rc._ptr;
+            &mut *ptr
+        };
         Some(&mut inner.value)
     } else {
         None
@@ -343,7 +346,10 @@ impl<T: Clone> Rc<T> {
         // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
         // this point, and we required the `Rc<T>` itself to be `mut`, so we're returning the only
         // possible reference to the inner value.
-        let inner = unsafe { &mut *self._ptr };
+        let inner = unsafe {
+            let NonZero(ptr) = self._ptr;
+            &mut *ptr
+        };
         &mut inner.value
     }
 }
@@ -391,7 +397,8 @@ impl<T> Drop for Rc<T> {
     /// ```
     fn drop(&mut self) {
         unsafe {
-            if !self._ptr.is_null() {
+            let NonZero(ptr) = self._ptr;
+            if !ptr.is_null() {
                 self.dec_strong();
                 if self.strong() == 0 {
                     ptr::read(&**self); // destroy the contained object
@@ -401,7 +408,7 @@ impl<T> Drop for Rc<T> {
                     self.dec_weak();
 
                     if self.weak() == 0 {
-                        deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
+                        deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
                                    min_align_of::<RcBox<T>>())
                     }
                 }
@@ -618,7 +625,7 @@ impl<T: fmt::Show> fmt::Show for Rc<T> {
 pub struct Weak<T> {
     // FIXME #12808: strange names to try to avoid interfering with
     // field accesses of the contained type via Deref
-    _ptr: *mut RcBox<T>,
+    _ptr: NonZero<*mut RcBox<T>>,
     _nosend: marker::NoSend,
     _noshare: marker::NoSync
 }
@@ -682,12 +689,13 @@ impl<T> Drop for Weak<T> {
     /// ```
     fn drop(&mut self) {
         unsafe {
-            if !self._ptr.is_null() {
+            let NonZero(ptr) = self._ptr;
+            if !ptr.is_null() {
                 self.dec_weak();
                 // the weak count starts at 1, and will only go to zero if all the strong pointers
                 // have disappeared.
                 if self.weak() == 0 {
-                    deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
+                    deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
                                min_align_of::<RcBox<T>>())
                 }
             }
@@ -742,12 +750,18 @@ trait RcBoxPtr<T> {
 
 impl<T> RcBoxPtr<T> for Rc<T> {
     #[inline(always)]
-    fn inner(&self) -> &RcBox<T> { unsafe { &(*self._ptr) } }
+    fn inner(&self) -> &RcBox<T> {
+        let NonZero(ptr) = self._ptr;
+        unsafe { &(*ptr) }
+    }
 }
 
 impl<T> RcBoxPtr<T> for Weak<T> {
     #[inline(always)]
-    fn inner(&self) -> &RcBox<T> { unsafe { &(*self._ptr) } }
+    fn inner(&self) -> &RcBox<T> {
+        let NonZero(ptr) = self._ptr;
+        unsafe { &(*ptr) }
+    }
 }
 
 #[cfg(test)]