about summary refs log tree commit diff
diff options
context:
space:
mode:
authorcad97 <cad97@cad97.com>2019-12-15 17:59:09 -0500
committercad97 <cad97@cad97.com>2019-12-15 19:57:18 -0500
commitc842f02dee81e52f3b63a8b46021a8e18f143a7e (patch)
treec2f565bc500dc56739e35539291e704a1624a31c
parent7dbfb0a8ca4ab74ee3111e57a024f9e6257ce37c (diff)
downloadrust-c842f02dee81e52f3b63a8b46021a8e18f143a7e.tar.gz
rust-c842f02dee81e52f3b63a8b46021a8e18f143a7e.zip
Use pointer offset instead of deref for A/Rc::into_raw
-rw-r--r--src/liballoc/rc.rs9
-rw-r--r--src/liballoc/sync.rs9
2 files changed, 14 insertions, 4 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 1ff1c3c834f..0205c408299 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -571,9 +571,14 @@ impl<T: ?Sized> Rc<T> {
     /// ```
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub fn into_raw(this: Self) -> *const T {
-        let ptr: *const T = &*this;
+        let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr);
+        let fake_ptr = ptr as *mut T;
         mem::forget(this);
-        ptr
+
+        unsafe {
+            let offset = data_offset(&(*ptr).value);
+            set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset))
+        }
     }
 
     /// Constructs an `Rc` from a raw pointer.
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 19b0086fa33..de56cb300d3 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -551,9 +551,14 @@ impl<T: ?Sized> Arc<T> {
     /// ```
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub fn into_raw(this: Self) -> *const T {
-        let ptr: *const T = &*this;
+        let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
+        let fake_ptr = ptr as *mut T;
         mem::forget(this);
-        ptr
+
+        unsafe {
+            let offset = data_offset(&(*ptr).data);
+            set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset))
+        }
     }
 
     /// Constructs an `Arc` from a raw pointer.