]> git.lizzy.rs Git - rust.git/commitdiff
Use pointer offset instead of deref for A/Rc::into_raw
authorcad97 <cad97@cad97.com>
Sun, 15 Dec 2019 22:59:09 +0000 (17:59 -0500)
committercad97 <cad97@cad97.com>
Mon, 16 Dec 2019 00:57:18 +0000 (19:57 -0500)
src/liballoc/rc.rs
src/liballoc/sync.rs

index 1ff1c3c834f4ea4c10b3ed5133ec765601f040bf..0205c40829930e2cd34b77235629f85ce5e33a5b 100644 (file)
@@ -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.
index 19b0086fa333cc1a25005ff83c99b105c55232eb..de56cb300d38c1f4c5d471faf4e3c216552428ca 100644 (file)
@@ -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.