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