miri: do not apply aliasing restrictions to Box with custom allocator · rust-lang/rust@e632e3f (original) (raw)
`@@ -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:📑:Tuple;
`
160
161
`use core:📑: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, 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
``