Skip to content

Commit 7709d20

Browse files
committed
Implement Box::into_raw based on Box::leak
… instead of the other way around.
1 parent 9a1c7db commit 7709d20

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

src/liballoc/boxed.rs

+17-10
Original file line numberDiff line numberDiff line change
@@ -428,15 +428,12 @@ impl<T: ?Sized> Box<T> {
428428
#[stable(feature = "box_raw", since = "1.4.0")]
429429
#[inline]
430430
pub fn into_raw(b: Box<T>) -> *mut T {
431-
let b = mem::ManuallyDrop::new(b);
432-
let mut unique = b.0;
433-
// Box is kind-of a library type, but recognized as a "unique pointer" by
434-
// Stacked Borrows. This function here corresponds to "reborrowing to
435-
// a raw pointer", but there is no actual reborrow here -- so
436-
// without some care, the pointer we are returning here still carries
437-
// the tag of `b`, with `Unique` permission.
438-
// We round-trip through a mutable reference to avoid that.
439-
unsafe { unique.as_mut() as *mut T }
431+
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
432+
// raw pointer for the type system. Turning it directly into a raw pointer would not be
433+
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
434+
// so all raw pointer methods go through `leak` which creates a (unique)
435+
// mutable reference. Turning *that* to a raw pointer behaves correctly.
436+
Box::leak(b) as *mut T
440437
}
441438

442439
/// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`.
@@ -475,6 +472,11 @@ impl<T: ?Sized> Box<T> {
475472
)]
476473
#[inline]
477474
pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> {
475+
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
476+
// raw pointer for the type system. Turning it directly into a raw pointer would not be
477+
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
478+
// so all raw pointer methods go through `leak` which creates a (unique)
479+
// mutable reference. Turning *that* to a raw pointer behaves correctly.
478480
Box::leak(b).into()
479481
}
480482

@@ -486,6 +488,11 @@ impl<T: ?Sized> Box<T> {
486488
#[inline]
487489
#[doc(hidden)]
488490
pub fn into_unique(b: Box<T>) -> Unique<T> {
491+
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
492+
// raw pointer for the type system. Turning it directly into a raw pointer would not be
493+
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
494+
// so all raw pointer methods go through `leak` which creates a (unique)
495+
// mutable reference. Turning *that* to a raw pointer behaves correctly.
489496
Box::leak(b).into()
490497
}
491498

@@ -532,7 +539,7 @@ impl<T: ?Sized> Box<T> {
532539
where
533540
T: 'a, // Technically not needed, but kept to be explicit.
534541
{
535-
unsafe { &mut *Box::into_raw(b) }
542+
unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() }
536543
}
537544

538545
/// Converts a `Box<T>` into a `Pin<Box<T>>`

0 commit comments

Comments
 (0)