@@ -1059,6 +1059,59 @@ impl<T: ?Sized> Box<T> {
1059
1059
pub unsafe fn from_raw ( raw : * mut T ) -> Self {
1060
1060
unsafe { Self :: from_raw_in ( raw, Global ) }
1061
1061
}
1062
+
1063
+ /// Constructs a box from a `NonNull` pointer.
1064
+ ///
1065
+ /// After calling this function, the `NonNull` pointer is owned by
1066
+ /// the resulting `Box`. Specifically, the `Box` destructor will call
1067
+ /// the destructor of `T` and free the allocated memory. For this
1068
+ /// to be safe, the memory must have been allocated in accordance
1069
+ /// with the [memory layout] used by `Box` .
1070
+ ///
1071
+ /// # Safety
1072
+ ///
1073
+ /// This function is unsafe because improper use may lead to
1074
+ /// memory problems. For example, a double-free may occur if the
1075
+ /// function is called twice on the same `NonNull` pointer.
1076
+ ///
1077
+ /// The safety conditions are described in the [memory layout] section.
1078
+ ///
1079
+ /// # Examples
1080
+ ///
1081
+ /// Recreate a `Box` which was previously converted to a `NonNull`
1082
+ /// pointer using [`Box::into_non_null`]:
1083
+ /// ```
1084
+ /// #![feature(box_vec_non_null)]
1085
+ ///
1086
+ /// let x = Box::new(5);
1087
+ /// let non_null = Box::into_non_null(x);
1088
+ /// let x = unsafe { Box::from_non_null(non_null) };
1089
+ /// ```
1090
+ /// Manually create a `Box` from scratch by using the global allocator:
1091
+ /// ```
1092
+ /// #![feature(box_vec_non_null)]
1093
+ ///
1094
+ /// use std::alloc::{alloc, Layout};
1095
+ /// use std::ptr::NonNull;
1096
+ ///
1097
+ /// unsafe {
1098
+ /// let non_null = NonNull::new(alloc(Layout::new::<i32>()).cast::<i32>())
1099
+ /// .expect("allocation failed");
1100
+ /// // In general .write is required to avoid attempting to destruct
1101
+ /// // the (uninitialized) previous contents of `non_null`.
1102
+ /// non_null.write(5);
1103
+ /// let x = Box::from_non_null(non_null);
1104
+ /// }
1105
+ /// ```
1106
+ ///
1107
+ /// [memory layout]: self#memory-layout
1108
+ /// [`Layout`]: crate::Layout
1109
+ #[ unstable( feature = "box_vec_non_null" , reason = "new API" , issue = "none" ) ]
1110
+ #[ inline]
1111
+ #[ must_use = "call `drop(Box::from_non_null(ptr))` if you intend to drop the `Box`" ]
1112
+ pub unsafe fn from_non_null ( ptr : NonNull < T > ) -> Self {
1113
+ unsafe { Self :: from_raw ( ptr. as_ptr ( ) ) }
1114
+ }
1062
1115
}
1063
1116
1064
1117
impl < T : ?Sized , A : Allocator > Box < T , A > {
@@ -1116,6 +1169,61 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1116
1169
Box ( unsafe { Unique :: new_unchecked ( raw) } , alloc)
1117
1170
}
1118
1171
1172
+ /// Constructs a box from a `NonNull` pointer in the given allocator.
1173
+ ///
1174
+ /// After calling this function, the `NonNull` pointer is owned by
1175
+ /// the resulting `Box`. Specifically, the `Box` destructor will call
1176
+ /// the destructor of `T` and free the allocated memory. For this
1177
+ /// to be safe, the memory must have been allocated in accordance
1178
+ /// with the [memory layout] used by `Box` .
1179
+ ///
1180
+ /// # Safety
1181
+ ///
1182
+ /// This function is unsafe because improper use may lead to
1183
+ /// memory problems. For example, a double-free may occur if the
1184
+ /// function is called twice on the same raw pointer.
1185
+ ///
1186
+ ///
1187
+ /// # Examples
1188
+ ///
1189
+ /// Recreate a `Box` which was previously converted to a `NonNull` pointer
1190
+ /// using [`Box::into_non_null_with_allocator`]:
1191
+ /// ```
1192
+ /// #![feature(allocator_api, box_vec_non_null)]
1193
+ ///
1194
+ /// use std::alloc::System;
1195
+ ///
1196
+ /// let x = Box::new_in(5, System);
1197
+ /// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1198
+ /// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
1199
+ /// ```
1200
+ /// Manually create a `Box` from scratch by using the system allocator:
1201
+ /// ```
1202
+ /// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)]
1203
+ ///
1204
+ /// use std::alloc::{Allocator, Layout, System};
1205
+ ///
1206
+ /// unsafe {
1207
+ /// let non_null = System.allocate(Layout::new::<i32>())?.cast::<i32>();
1208
+ /// // In general .write is required to avoid attempting to destruct
1209
+ /// // the (uninitialized) previous contents of `non_null`.
1210
+ /// non_null.write(5);
1211
+ /// let x = Box::from_non_null_in(non_null, System);
1212
+ /// }
1213
+ /// # Ok::<(), std::alloc::AllocError>(())
1214
+ /// ```
1215
+ ///
1216
+ /// [memory layout]: self#memory-layout
1217
+ /// [`Layout`]: crate::Layout
1218
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1219
+ // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "none")]
1220
+ #[ rustc_const_unstable( feature = "const_box" , issue = "92521" ) ]
1221
+ #[ inline]
1222
+ pub const unsafe fn from_non_null_in ( raw : NonNull < T > , alloc : A ) -> Self {
1223
+ // SAFETY: guaranteed by the caller.
1224
+ unsafe { Box :: from_raw_in ( raw. as_ptr ( ) , alloc) }
1225
+ }
1226
+
1119
1227
/// Consumes the `Box`, returning a wrapped raw pointer.
1120
1228
///
1121
1229
/// The pointer will be properly aligned and non-null.
@@ -1171,6 +1279,66 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1171
1279
unsafe { addr_of_mut ! ( * & mut * Self :: into_raw_with_allocator( b) . 0 ) }
1172
1280
}
1173
1281
1282
+ /// Consumes the `Box`, returning a wrapped `NonNull` pointer.
1283
+ ///
1284
+ /// The pointer will be properly aligned.
1285
+ ///
1286
+ /// After calling this function, the caller is responsible for the
1287
+ /// memory previously managed by the `Box`. In particular, the
1288
+ /// caller should properly destroy `T` and release the memory, taking
1289
+ /// into account the [memory layout] used by `Box`. The easiest way to
1290
+ /// do this is to convert the `NonNull` pointer back into a `Box` with the
1291
+ /// [`Box::from_non_null`] function, allowing the `Box` destructor to
1292
+ /// perform the cleanup.
1293
+ ///
1294
+ /// Note: this is an associated function, which means that you have
1295
+ /// to call it as `Box::into_non_null(b)` instead of `b.into_non_null()`.
1296
+ /// This is so that there is no conflict with a method on the inner type.
1297
+ ///
1298
+ /// # Examples
1299
+ /// Converting the `NonNull` pointer back into a `Box` with [`Box::from_non_null`]
1300
+ /// for automatic cleanup:
1301
+ /// ```
1302
+ /// #![feature(box_vec_non_null)]
1303
+ ///
1304
+ /// let x = Box::new(String::from("Hello"));
1305
+ /// let non_null = Box::into_non_null(x);
1306
+ /// let x = unsafe { Box::from_non_null(non_null) };
1307
+ /// ```
1308
+ /// Manual cleanup by explicitly running the destructor and deallocating
1309
+ /// the memory:
1310
+ /// ```
1311
+ /// #![feature(box_vec_non_null)]
1312
+ ///
1313
+ /// use std::alloc::{dealloc, Layout};
1314
+ ///
1315
+ /// let x = Box::new(String::from("Hello"));
1316
+ /// let non_null = Box::into_non_null(x);
1317
+ /// unsafe {
1318
+ /// non_null.drop_in_place();
1319
+ /// dealloc(non_null.as_ptr().cast::<u8>(), Layout::new::<String>());
1320
+ /// }
1321
+ /// ```
1322
+ /// Note: This is equivalent to the following:
1323
+ /// ```
1324
+ /// #![feature(box_vec_non_null)]
1325
+ ///
1326
+ /// let x = Box::new(String::from("Hello"));
1327
+ /// let non_null = Box::into_non_null(x);
1328
+ /// unsafe {
1329
+ /// drop(Box::from_non_null(non_null));
1330
+ /// }
1331
+ /// ```
1332
+ ///
1333
+ /// [memory layout]: self#memory-layout
1334
+ #[ must_use = "losing the pointer will leak memory" ]
1335
+ #[ unstable( feature = "box_vec_non_null" , reason = "new API" , issue = "none" ) ]
1336
+ #[ inline]
1337
+ pub fn into_non_null ( b : Self ) -> NonNull < T > {
1338
+ // SAFETY: `Box` is guaranteed to be non-null.
1339
+ unsafe { NonNull :: new_unchecked ( Self :: into_raw ( b) ) }
1340
+ }
1341
+
1174
1342
/// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
1175
1343
///
1176
1344
/// The pointer will be properly aligned and non-null.
@@ -1232,6 +1400,61 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
1232
1400
( ptr, alloc)
1233
1401
}
1234
1402
1403
+ /// Consumes the `Box`, returning a wrapped `NonNull` pointer and the allocator.
1404
+ ///
1405
+ /// The pointer will be properly aligned.
1406
+ ///
1407
+ /// After calling this function, the caller is responsible for the
1408
+ /// memory previously managed by the `Box`. In particular, the
1409
+ /// caller should properly destroy `T` and release the memory, taking
1410
+ /// into account the [memory layout] used by `Box`. The easiest way to
1411
+ /// do this is to convert the `NonNull` pointer back into a `Box` with the
1412
+ /// [`Box::from_non_null_in`] function, allowing the `Box` destructor to
1413
+ /// perform the cleanup.
1414
+ ///
1415
+ /// Note: this is an associated function, which means that you have
1416
+ /// to call it as `Box::into_non_null_with_allocator(b)` instead of
1417
+ /// `b.into_non_null_with_allocator()`. This is so that there is no
1418
+ /// conflict with a method on the inner type.
1419
+ ///
1420
+ /// # Examples
1421
+ /// Converting the `NonNull` pointer back into a `Box` with
1422
+ /// [`Box::from_non_null_in`] for automatic cleanup:
1423
+ /// ```
1424
+ /// #![feature(allocator_api, box_vec_non_null)]
1425
+ ///
1426
+ /// use std::alloc::System;
1427
+ ///
1428
+ /// let x = Box::new_in(String::from("Hello"), System);
1429
+ /// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1430
+ /// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
1431
+ /// ```
1432
+ /// Manual cleanup by explicitly running the destructor and deallocating
1433
+ /// the memory:
1434
+ /// ```
1435
+ /// #![feature(allocator_api, box_vec_non_null)]
1436
+ ///
1437
+ /// use std::alloc::{Allocator, Layout, System};
1438
+ ///
1439
+ /// let x = Box::new_in(String::from("Hello"), System);
1440
+ /// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1441
+ /// unsafe {
1442
+ /// non_null.drop_in_place();
1443
+ /// alloc.deallocate(non_null.cast::<u8>(), Layout::new::<String>());
1444
+ /// }
1445
+ /// ```
1446
+ ///
1447
+ /// [memory layout]: self#memory-layout
1448
+ #[ must_use = "losing the pointer will leak memory" ]
1449
+ #[ unstable( feature = "allocator_api" , issue = "32838" ) ]
1450
+ // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "none")]
1451
+ #[ inline]
1452
+ pub fn into_non_null_with_allocator ( b : Self ) -> ( NonNull < T > , A ) {
1453
+ let ( ptr, alloc) = Box :: into_raw_with_allocator ( b) ;
1454
+ // SAFETY: `Box` is guaranteed to be non-null.
1455
+ unsafe { ( NonNull :: new_unchecked ( ptr) , alloc) }
1456
+ }
1457
+
1235
1458
#[ unstable(
1236
1459
feature = "ptr_internals" ,
1237
1460
issue = "none" ,
0 commit comments