about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJames Miller <james@aatch.net>2015-01-21 09:35:24 +1300
committerBjörn Steinbrink <bsteinbr@gmail.com>2015-02-03 13:36:36 +0100
commit40b6e34240c6669fdf7fb1b83c3925b0becafd0e (patch)
tree6921f5b3802cc2764be4437015e22bca059bfbc6
parent7858cb432d3f2efc0374424cb2b51518f697c172 (diff)
downloadrust-40b6e34240c6669fdf7fb1b83c3925b0becafd0e.tar.gz
rust-40b6e34240c6669fdf7fb1b83c3925b0becafd0e.zip
Rc: Add assumptions that the pointer is non-null
Since the snapshot compiler is still using an older LLVM version, omit
the call in stage0, because compile times explode otherwise.
-rw-r--r--src/liballoc/rc.rs27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 464f20e9cac..80ffa4a0a19 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -160,6 +160,7 @@ use core::option::Option::{Some, None};
 use core::ptr::{self, PtrExt};
 use core::result::Result;
 use core::result::Result::{Ok, Err};
+use core::intrinsics::assume;
 
 use heap::deallocate;
 
@@ -769,12 +770,34 @@ 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> {
+        unsafe {
+            // Safe to assume this here, as if it weren't true, we'd be breaking
+            // the contract anyway.
+            // This allows the null check to be elided in the destructor if we
+            // manipulated the reference count in the same function.
+            if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot
+                assume(!self._ptr.is_null());
+            }
+            &(**self._ptr)
+        }
+    }
 }
 
 impl<T> RcBoxPtr<T> for Weak<T> {
     #[inline(always)]
-    fn inner(&self) -> &RcBox<T> { unsafe { &(**self._ptr) } }
+    fn inner(&self) -> &RcBox<T> {
+        unsafe {
+            // Safe to assume this here, as if it weren't true, we'd be breaking
+            // the contract anyway.
+            // This allows the null check to be elided in the destructor if we
+            // manipulated the reference count in the same function.
+            if cfg!(not(stage0)) { // NOTE remove cfg after next snapshot
+                assume(!self._ptr.is_null());
+            }
+            &(**self._ptr)
+        }
+    }
 }
 
 #[cfg(test)]