]> git.lizzy.rs Git - rust.git/blobdiff - src/liballoc/rc.rs
Auto merge of #67476 - mark-i-m:simplify-borrow_check-5, r=matthewjasper
[rust.git] / src / liballoc / rc.rs
index 3080a8bf459661588614914d0818835f758139c4..b176e0f6e2a6890b59ccbf2b484eb2aa634fc7d3 100644 (file)
@@ -565,9 +565,19 @@ 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
+
+        // SAFETY: This cannot go through Deref::deref.
+        // Instead, we manually offset the pointer rather than manifesting a reference.
+        // This is so that the returned pointer retains the same provenance as our pointer.
+        // This is required so that e.g. `get_mut` can write through the pointer
+        // after the Rc is recovered through `from_raw`.
+        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.