@@ -1098,115 +1098,6 @@ impl<T: ?Sized> Box<T> {
10981098 pub unsafe fn from_non_null ( ptr : NonNull < T > ) -> Self {
10991099 unsafe { Self :: from_raw ( ptr. as_ptr ( ) ) }
11001100 }
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- }
12101101
12111102 /// Consumes the `Box`, returning a wrapped raw pointer.
12121103 ///
@@ -1259,8 +1150,11 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
12591150 #[ stable( feature = "box_raw" , since = "1.4.0" ) ]
12601151 #[ inline]
12611152 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
12641158 }
12651159
12661160 /// Consumes the `Box`, returning a wrapped `NonNull` pointer.
@@ -1322,6 +1216,115 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
13221216 // SAFETY: `Box` is guaranteed to be non-null.
13231217 unsafe { NonNull :: new_unchecked ( Self :: into_raw ( b) ) }
13241218 }
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+ }
13251328
13261329 /// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
13271330 ///
@@ -1602,7 +1605,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
16021605 where
16031606 A : ' a ,
16041607 {
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 }
16061611 }
16071612
16081613 /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
0 commit comments