@@ -1098,115 +1098,6 @@ impl<T: ?Sized> Box<T> {
1098
1098
pub unsafe fn from_non_null ( ptr : NonNull < T > ) -> Self {
1099
1099
unsafe { Self :: from_raw ( ptr. as_ptr ( ) ) }
1100
1100
}
1101
- }
1102
-
1103
- impl < T : ?Sized , A : Allocator > Box < T , A > {
1104
- /// Constructs a box from a raw pointer in the given allocator.
1105
- ///
1106
- /// After calling this function, the raw pointer is owned by the
1107
- /// resulting `Box`. Specifically, the `Box` destructor will call
1108
- /// the destructor of `T` and free the allocated memory. For this
1109
- /// to be safe, the memory must have been allocated in accordance
1110
- /// with the [memory layout] used by `Box` .
1111
- ///
1112
- /// # Safety
1113
- ///
1114
- /// This function is unsafe because improper use may lead to
1115
- /// memory problems. For example, a double-free may occur if the
1116
- /// function is called twice on the same raw pointer.
1117
- ///
1118
- /// The raw pointer must point to a block of memory allocated by `alloc`.
1119
- ///
1120
- /// # Examples
1121
- ///
1122
- /// Recreate a `Box` which was previously converted to a raw pointer
1123
- /// using [`Box::into_raw_with_allocator`]:
1124
- /// ```
1125
- /// #![feature(allocator_api)]
1126
- ///
1127
- /// use std::alloc::System;
1128
- ///
1129
- /// let x = Box::new_in(5, System);
1130
- /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
1131
- /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
1132
- /// ```
1133
- /// Manually create a `Box` from scratch by using the system allocator:
1134
- /// ```
1135
- /// #![feature(allocator_api, slice_ptr_get)]
1136
- ///
1137
- /// use std::alloc::{Allocator, Layout, System};
1138
- ///
1139
- /// unsafe {
1140
- /// let ptr = System.allocate(Layout::new::<i32>())?.as_mut_ptr() as *mut i32;
1141
- /// // In general .write is required to avoid attempting to destruct
1142
- /// // the (uninitialized) previous contents of `ptr`, though for this
1143
- /// // simple example `*ptr = 5` would have worked as well.
1144
- /// ptr.write(5);
1145
- /// let x = Box::from_raw_in(ptr, System);
1146
- /// }
1147
- /// # Ok::<(), std::alloc::AllocError>(())
1148
- /// ```
1149
- ///
1150
- /// [memory layout]: self#memory-layout
1151
- #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1152
- #[ inline]
1153
- pub unsafe fn from_raw_in ( raw : * mut T , alloc : A ) -> Self {
1154
- Box ( unsafe { Unique :: new_unchecked ( raw) } , alloc)
1155
- }
1156
-
1157
- /// Constructs a box from a `NonNull` pointer in the given allocator.
1158
- ///
1159
- /// After calling this function, the `NonNull` pointer is owned by
1160
- /// the resulting `Box`. Specifically, the `Box` destructor will call
1161
- /// the destructor of `T` and free the allocated memory. For this
1162
- /// to be safe, the memory must have been allocated in accordance
1163
- /// with the [memory layout] used by `Box` .
1164
- ///
1165
- /// # Safety
1166
- ///
1167
- /// This function is unsafe because improper use may lead to
1168
- /// memory problems. For example, a double-free may occur if the
1169
- /// function is called twice on the same raw pointer.
1170
- ///
1171
- /// The non-null pointer must point to a block of memory allocated by `alloc`.
1172
- ///
1173
- /// # Examples
1174
- ///
1175
- /// Recreate a `Box` which was previously converted to a `NonNull` pointer
1176
- /// using [`Box::into_non_null_with_allocator`]:
1177
- /// ```
1178
- /// #![feature(allocator_api, box_vec_non_null)]
1179
- ///
1180
- /// use std::alloc::System;
1181
- ///
1182
- /// let x = Box::new_in(5, System);
1183
- /// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1184
- /// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
1185
- /// ```
1186
- /// Manually create a `Box` from scratch by using the system allocator:
1187
- /// ```
1188
- /// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)]
1189
- ///
1190
- /// use std::alloc::{Allocator, Layout, System};
1191
- ///
1192
- /// unsafe {
1193
- /// let non_null = System.allocate(Layout::new::<i32>())?.cast::<i32>();
1194
- /// // In general .write is required to avoid attempting to destruct
1195
- /// // the (uninitialized) previous contents of `non_null`.
1196
- /// non_null.write(5);
1197
- /// let x = Box::from_non_null_in(non_null, System);
1198
- /// }
1199
- /// # Ok::<(), std::alloc::AllocError>(())
1200
- /// ```
1201
- ///
1202
- /// [memory layout]: self#memory-layout
1203
- #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1204
- // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
1205
- #[ inline]
1206
- pub unsafe fn from_non_null_in ( raw : NonNull < T > , alloc : A ) -> Self {
1207
- // SAFETY: guaranteed by the caller.
1208
- unsafe { Box :: from_raw_in ( raw. as_ptr ( ) , alloc) }
1209
- }
1210
1101
1211
1102
/// Consumes the `Box`, returning a wrapped raw pointer.
1212
1103
///
@@ -1259,8 +1150,11 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1259
1150
#[ stable( feature = "box_raw" , since = "1.4.0" ) ]
1260
1151
#[ inline]
1261
1152
pub fn into_raw ( b : Self ) -> * mut T {
1262
- // Make sure Miri realizes that we transition from a noalias pointer to a raw pointer here.
1263
- unsafe { & raw mut * & mut * Self :: into_raw_with_allocator ( b) . 0 }
1153
+ // Avoid `into_raw_with_allocator` as that interacts poorly with Miri's Stacked Borrows.
1154
+ let mut b = mem:: ManuallyDrop :: new ( b) ;
1155
+ // We go through the built-in deref for `Box`, which is crucial for Miri to recognize this
1156
+ // operation for it's alias tracking.
1157
+ & raw mut * * b
1264
1158
}
1265
1159
1266
1160
/// Consumes the `Box`, returning a wrapped `NonNull` pointer.
@@ -1322,6 +1216,115 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1322
1216
// SAFETY: `Box` is guaranteed to be non-null.
1323
1217
unsafe { NonNull :: new_unchecked ( Self :: into_raw ( b) ) }
1324
1218
}
1219
+ }
1220
+
1221
+ impl < T : ?Sized , A : Allocator > Box < T , A > {
1222
+ /// Constructs a box from a raw pointer in the given allocator.
1223
+ ///
1224
+ /// After calling this function, the raw pointer is owned by the
1225
+ /// resulting `Box`. Specifically, the `Box` destructor will call
1226
+ /// the destructor of `T` and free the allocated memory. For this
1227
+ /// to be safe, the memory must have been allocated in accordance
1228
+ /// with the [memory layout] used by `Box` .
1229
+ ///
1230
+ /// # Safety
1231
+ ///
1232
+ /// This function is unsafe because improper use may lead to
1233
+ /// memory problems. For example, a double-free may occur if the
1234
+ /// function is called twice on the same raw pointer.
1235
+ ///
1236
+ /// The raw pointer must point to a block of memory allocated by `alloc`.
1237
+ ///
1238
+ /// # Examples
1239
+ ///
1240
+ /// Recreate a `Box` which was previously converted to a raw pointer
1241
+ /// using [`Box::into_raw_with_allocator`]:
1242
+ /// ```
1243
+ /// #![feature(allocator_api)]
1244
+ ///
1245
+ /// use std::alloc::System;
1246
+ ///
1247
+ /// let x = Box::new_in(5, System);
1248
+ /// let (ptr, alloc) = Box::into_raw_with_allocator(x);
1249
+ /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
1250
+ /// ```
1251
+ /// Manually create a `Box` from scratch by using the system allocator:
1252
+ /// ```
1253
+ /// #![feature(allocator_api, slice_ptr_get)]
1254
+ ///
1255
+ /// use std::alloc::{Allocator, Layout, System};
1256
+ ///
1257
+ /// unsafe {
1258
+ /// let ptr = System.allocate(Layout::new::<i32>())?.as_mut_ptr() as *mut i32;
1259
+ /// // In general .write is required to avoid attempting to destruct
1260
+ /// // the (uninitialized) previous contents of `ptr`, though for this
1261
+ /// // simple example `*ptr = 5` would have worked as well.
1262
+ /// ptr.write(5);
1263
+ /// let x = Box::from_raw_in(ptr, System);
1264
+ /// }
1265
+ /// # Ok::<(), std::alloc::AllocError>(())
1266
+ /// ```
1267
+ ///
1268
+ /// [memory layout]: self#memory-layout
1269
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1270
+ #[ inline]
1271
+ pub unsafe fn from_raw_in ( raw : * mut T , alloc : A ) -> Self {
1272
+ Box ( unsafe { Unique :: new_unchecked ( raw) } , alloc)
1273
+ }
1274
+
1275
+ /// Constructs a box from a `NonNull` pointer in the given allocator.
1276
+ ///
1277
+ /// After calling this function, the `NonNull` pointer is owned by
1278
+ /// the resulting `Box`. Specifically, the `Box` destructor will call
1279
+ /// the destructor of `T` and free the allocated memory. For this
1280
+ /// to be safe, the memory must have been allocated in accordance
1281
+ /// with the [memory layout] used by `Box` .
1282
+ ///
1283
+ /// # Safety
1284
+ ///
1285
+ /// This function is unsafe because improper use may lead to
1286
+ /// memory problems. For example, a double-free may occur if the
1287
+ /// function is called twice on the same raw pointer.
1288
+ ///
1289
+ /// The non-null pointer must point to a block of memory allocated by `alloc`.
1290
+ ///
1291
+ /// # Examples
1292
+ ///
1293
+ /// Recreate a `Box` which was previously converted to a `NonNull` pointer
1294
+ /// using [`Box::into_non_null_with_allocator`]:
1295
+ /// ```
1296
+ /// #![feature(allocator_api, box_vec_non_null)]
1297
+ ///
1298
+ /// use std::alloc::System;
1299
+ ///
1300
+ /// let x = Box::new_in(5, System);
1301
+ /// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1302
+ /// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
1303
+ /// ```
1304
+ /// Manually create a `Box` from scratch by using the system allocator:
1305
+ /// ```
1306
+ /// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)]
1307
+ ///
1308
+ /// use std::alloc::{Allocator, Layout, System};
1309
+ ///
1310
+ /// unsafe {
1311
+ /// let non_null = System.allocate(Layout::new::<i32>())?.cast::<i32>();
1312
+ /// // In general .write is required to avoid attempting to destruct
1313
+ /// // the (uninitialized) previous contents of `non_null`.
1314
+ /// non_null.write(5);
1315
+ /// let x = Box::from_non_null_in(non_null, System);
1316
+ /// }
1317
+ /// # Ok::<(), std::alloc::AllocError>(())
1318
+ /// ```
1319
+ ///
1320
+ /// [memory layout]: self#memory-layout
1321
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1322
+ // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
1323
+ #[ inline]
1324
+ pub unsafe fn from_non_null_in ( raw : NonNull < T > , alloc : A ) -> Self {
1325
+ // SAFETY: guaranteed by the caller.
1326
+ unsafe { Box :: from_raw_in ( raw. as_ptr ( ) , alloc) }
1327
+ }
1325
1328
1326
1329
/// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
1327
1330
///
@@ -1602,7 +1605,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1602
1605
where
1603
1606
A : ' a ,
1604
1607
{
1605
- unsafe { & mut * Box :: into_raw ( b) }
1608
+ let ( ptr, alloc) = Box :: into_raw_with_allocator ( b) ;
1609
+ mem:: forget ( alloc) ;
1610
+ unsafe { & mut * ptr }
1606
1611
}
1607
1612
1608
1613
/// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
0 commit comments