about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2020-04-15 18:38:22 +0200
committerSimon Sapin <simon.sapin@exyr.org>2020-04-16 17:20:53 +0200
commit7709d205ddcea48294f7916a3d7eb6d843bb6dbc (patch)
tree40c82b652bdd2309c6efb65cda52be2fd3f70c62 /src
parent9a1c7dba32e13184f4c5c3ad914d536f9799c524 (diff)
downloadrust-7709d205ddcea48294f7916a3d7eb6d843bb6dbc.tar.gz
rust-7709d205ddcea48294f7916a3d7eb6d843bb6dbc.zip
Implement `Box::into_raw` based on `Box::leak`
… instead of the other way around.
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/boxed.rs27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 1195805e6ea..3d657396a9f 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -428,15 +428,12 @@ impl<T: ?Sized> Box<T> {
     #[stable(feature = "box_raw", since = "1.4.0")]
     #[inline]
     pub fn into_raw(b: Box<T>) -> *mut T {
-        let b = mem::ManuallyDrop::new(b);
-        let mut unique = b.0;
-        // Box is kind-of a library type, but recognized as a "unique pointer" by
-        // Stacked Borrows.  This function here corresponds to "reborrowing to
-        // a raw pointer", but there is no actual reborrow here -- so
-        // without some care, the pointer we are returning here still carries
-        // the tag of `b`, with `Unique` permission.
-        // We round-trip through a mutable reference to avoid that.
-        unsafe { unique.as_mut() as *mut T }
+        // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
+        // raw pointer for the type system. Turning it directly into a raw pointer would not be
+        // recognized as "releasing" the unique pointer to permit aliased raw accesses,
+        // so all raw pointer methods go through `leak` which creates a (unique)
+        // mutable reference. Turning *that* to a raw pointer behaves correctly.
+        Box::leak(b) as *mut T
     }
 
     /// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`.
@@ -475,6 +472,11 @@ impl<T: ?Sized> Box<T> {
     )]
     #[inline]
     pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> {
+        // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
+        // raw pointer for the type system. Turning it directly into a raw pointer would not be
+        // recognized as "releasing" the unique pointer to permit aliased raw accesses,
+        // so all raw pointer methods go through `leak` which creates a (unique)
+        // mutable reference. Turning *that* to a raw pointer behaves correctly.
         Box::leak(b).into()
     }
 
@@ -486,6 +488,11 @@ impl<T: ?Sized> Box<T> {
     #[inline]
     #[doc(hidden)]
     pub fn into_unique(b: Box<T>) -> Unique<T> {
+        // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
+        // raw pointer for the type system. Turning it directly into a raw pointer would not be
+        // recognized as "releasing" the unique pointer to permit aliased raw accesses,
+        // so all raw pointer methods go through `leak` which creates a (unique)
+        // mutable reference. Turning *that* to a raw pointer behaves correctly.
         Box::leak(b).into()
     }
 
@@ -532,7 +539,7 @@ impl<T: ?Sized> Box<T> {
     where
         T: 'a, // Technically not needed, but kept to be explicit.
     {
-        unsafe { &mut *Box::into_raw(b) }
+        unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() }
     }
 
     /// Converts a `Box<T>` into a `Pin<Box<T>>`