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

``