From 7709d205ddcea48294f7916a3d7eb6d843bb6dbc Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Wed, 15 Apr 2020 18:38:22 +0200 Subject: [PATCH] Implement `Box::into_raw` based on `Box::leak` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … instead of the other way around. --- src/liballoc/boxed.rs | 27 +++++++++++++++++---------- 1 file 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 Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *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`. @@ -475,6 +472,11 @@ impl Box { )] #[inline] pub fn into_raw_non_null(b: Box) -> NonNull { + // 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 Box { #[inline] #[doc(hidden)] pub fn into_unique(b: Box) -> Unique { + // 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 Box { 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` into a `Pin>`