@@ -155,6 +155,7 @@ use core::error::Error;
155
155
use core:: fmt;
156
156
use core:: future:: Future ;
157
157
use core:: hash:: { Hash , Hasher } ;
158
+ use core:: intrinsics:: retag_box_to_raw;
158
159
use core:: iter:: FusedIterator ;
159
160
use core:: marker:: Tuple ;
160
161
use core:: marker:: Unsize ;
@@ -1110,8 +1111,16 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1110
1111
#[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1111
1112
#[ inline]
1112
1113
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)
1115
1124
}
1116
1125
1117
1126
#[ unstable(
@@ -1122,13 +1131,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1122
1131
#[ inline]
1123
1132
#[ doc( hidden) ]
1124
1133
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) }
1132
1136
}
1133
1137
1134
1138
/// Returns a reference to the underlying allocator.
@@ -1184,7 +1188,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1184
1188
where
1185
1189
A : ' a ,
1186
1190
{
1187
- unsafe { & mut * mem :: ManuallyDrop :: new ( b ) . 0 . as_ptr ( ) }
1191
+ unsafe { & mut * Box :: into_raw ( b ) }
1188
1192
}
1189
1193
1190
1194
/// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
0 commit comments