@@ -155,6 +155,7 @@ use core::error::Error;
155155use core:: fmt;
156156use core:: future:: Future ;
157157use core:: hash:: { Hash , Hasher } ;
158+ use core:: intrinsics:: retag_box_to_raw;
158159use core:: iter:: FusedIterator ;
159160use core:: marker:: Tuple ;
160161use core:: marker:: Unsize ;
@@ -1110,8 +1111,16 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11101111 #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
11111112 #[ inline]
11121113 pub fn into_raw_with_allocator ( b : Self ) -> ( * mut T , A ) {
1113- let ( leaked, alloc) = Box :: into_unique ( b) ;
1114- ( leaked. as_ptr ( ) , alloc)
1114+ // This is the transition point from `Box` to raw pointers. For Stacked Borrows, these casts
1115+ // are relevant -- if this is a global allocator Box and we just get the pointer from `b.0`,
1116+ // it will have `Unique` permission, which is not what we want from a raw pointer. We could
1117+ // fix that by going through `&mut`, but then if this is *not* a global allocator Box, we'd
1118+ // be adding uniqueness assertions that we do not want. So for Miri's sake we pass this
1119+ // pointer through an intrinsic for box-to-raw casts, which can do the right thing wrt the
1120+ // aliasing model.
1121+ let b = mem:: ManuallyDrop :: new ( b) ;
1122+ let alloc = unsafe { ptr:: read ( & b. 1 ) } ;
1123+ ( unsafe { retag_box_to_raw :: < T , A > ( b. 0 . as_ptr ( ) ) } , alloc)
11151124 }
11161125
11171126 #[ unstable(
@@ -1122,13 +1131,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11221131 #[ inline]
11231132 #[ doc( hidden) ]
11241133 pub fn into_unique ( b : Self ) -> ( Unique < T > , A ) {
1125- // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
1126- // raw pointer for the type system. Turning it directly into a raw pointer would not be
1127- // recognized as "releasing" the unique pointer to permit aliased raw accesses,
1128- // so all raw pointer methods have to go through `Box::leak`. Turning *that* to a raw pointer
1129- // behaves correctly.
1130- let alloc = unsafe { ptr:: read ( & b. 1 ) } ;
1131- ( Unique :: from ( Box :: leak ( b) ) , alloc)
1134+ let ( ptr, alloc) = Box :: into_raw_with_allocator ( b) ;
1135+ unsafe { ( Unique :: from ( & mut * ptr) , alloc) }
11321136 }
11331137
11341138 /// Returns a reference to the underlying allocator.
@@ -1184,7 +1188,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11841188 where
11851189 A : ' a ,
11861190 {
1187- unsafe { & mut * mem :: ManuallyDrop :: new ( b ) . 0 . as_ptr ( ) }
1191+ unsafe { & mut * Box :: into_raw ( b ) }
11881192 }
11891193
11901194 /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
0 commit comments