Rollup merge of #129091 - RalfJung:box_as_ptr, r=Amanieu · patricklam/verify-rust-std@3a8de95 (original) (raw)
`@@ -1254,6 +1254,95 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
`
1254
1254
`unsafe { (Unique::from(&mut *ptr), alloc) }
`
1255
1255
`}
`
1256
1256
``
``
1257
`` +
/// Returns a raw mutable pointer to the Box
's contents.
``
``
1258
`+
///
`
``
1259
`` +
/// The caller must ensure that the Box
outlives the pointer this
``
``
1260
`+
/// function returns, or else it will end up dangling.
`
``
1261
`+
///
`
``
1262
`+
/// This method guarantees that for the purpose of the aliasing model, this method
`
``
1263
`+
/// does not materialize a reference to the underlying memory, and thus the returned pointer
`
``
1264
`` +
/// will remain valid when mixed with other calls to [as_ptr
] and [as_mut_ptr
].
``
``
1265
`+
/// Note that calling other methods that materialize references to the memory
`
``
1266
`+
/// may still invalidate this pointer.
`
``
1267
`+
/// See the example below for how this guarantee can be used.
`
``
1268
`+
///
`
``
1269
`+
/// # Examples
`
``
1270
`+
///
`
``
1271
`+
/// Due to the aliasing guarantee, the following code is legal:
`
``
1272
`+
///
`
``
1273
/// ```rust
``
1274
`+
/// #![feature(box_as_ptr)]
`
``
1275
`+
///
`
``
1276
`+
/// unsafe {
`
``
1277
`+
/// let mut b = Box::new(0);
`
``
1278
`+
/// let ptr1 = Box::as_mut_ptr(&mut b);
`
``
1279
`+
/// ptr1.write(1);
`
``
1280
`+
/// let ptr2 = Box::as_mut_ptr(&mut b);
`
``
1281
`+
/// ptr2.write(2);
`
``
1282
`` +
/// // Notably, the write to ptr2
did not invalidate ptr1
:
``
``
1283
`+
/// ptr1.write(3);
`
``
1284
`+
/// }
`
``
1285
/// ```
``
1286
`+
///
`
``
1287
`` +
/// [as_mut_ptr
]: Self::as_mut_ptr
``
``
1288
`` +
/// [as_ptr
]: Self::as_ptr
``
``
1289
`+
#[unstable(feature = "box_as_ptr", issue = "129090")]
`
``
1290
`+
#[rustc_never_returns_null_ptr]
`
``
1291
`+
#[inline]
`
``
1292
`+
pub fn as_mut_ptr(b: &mut Self) -> *mut T {
`
``
1293
`` +
// This is a primitive deref, not going through DerefMut
, and therefore not materializing
``
``
1294
`+
// any references.
`
``
1295
`+
ptr::addr_of_mut!(**b)
`
``
1296
`+
}
`
``
1297
+
``
1298
`` +
/// Returns a raw pointer to the Box
's contents.
``
``
1299
`+
///
`
``
1300
`` +
/// The caller must ensure that the Box
outlives the pointer this
``
``
1301
`+
/// function returns, or else it will end up dangling.
`
``
1302
`+
///
`
``
1303
`+
/// The caller must also ensure that the memory the pointer (non-transitively) points to
`
``
1304
`` +
/// is never written to (except inside an UnsafeCell
) using this pointer or any pointer
``
``
1305
`` +
/// derived from it. If you need to mutate the contents of the Box
, use [as_mut_ptr
].
``
``
1306
`+
///
`
``
1307
`+
/// This method guarantees that for the purpose of the aliasing model, this method
`
``
1308
`+
/// does not materialize a reference to the underlying memory, and thus the returned pointer
`
``
1309
`` +
/// will remain valid when mixed with other calls to [as_ptr
] and [as_mut_ptr
].
``
``
1310
`+
/// Note that calling other methods that materialize mutable references to the memory,
`
``
1311
`+
/// as well as writing to this memory, may still invalidate this pointer.
`
``
1312
`+
/// See the example below for how this guarantee can be used.
`
``
1313
`+
///
`
``
1314
`+
/// # Examples
`
``
1315
`+
///
`
``
1316
`+
/// Due to the aliasing guarantee, the following code is legal:
`
``
1317
`+
///
`
``
1318
/// ```rust
``
1319
`+
/// #![feature(box_as_ptr)]
`
``
1320
`+
///
`
``
1321
`+
/// unsafe {
`
``
1322
`+
/// let mut v = Box::new(0);
`
``
1323
`+
/// let ptr1 = Box::as_ptr(&v);
`
``
1324
`+
/// let ptr2 = Box::as_mut_ptr(&mut v);
`
``
1325
`+
/// let _val = ptr2.read();
`
``
1326
`` +
/// // No write to this memory has happened yet, so ptr1
is still valid.
``
``
1327
`+
/// let _val = ptr1.read();
`
``
1328
`+
/// // However, once we do a write...
`
``
1329
`+
/// ptr2.write(1);
`
``
1330
`` +
/// // ... ptr1
is no longer valid.
``
``
1331
`+
/// // This would be UB: let _val = ptr1.read();
`
``
1332
`+
/// }
`
``
1333
/// ```
``
1334
`+
///
`
``
1335
`` +
/// [as_mut_ptr
]: Self::as_mut_ptr
``
``
1336
`` +
/// [as_ptr
]: Self::as_ptr
``
``
1337
`+
#[unstable(feature = "box_as_ptr", issue = "129090")]
`
``
1338
`+
#[rustc_never_returns_null_ptr]
`
``
1339
`+
#[inline]
`
``
1340
`+
pub fn as_ptr(b: &Self) -> *const T {
`
``
1341
`` +
// This is a primitive deref, not going through DerefMut
, and therefore not materializing
``
``
1342
`+
// any references.
`
``
1343
`+
ptr::addr_of!(**b)
`
``
1344
`+
}
`
``
1345
+
1257
1346
`/// Returns a reference to the underlying allocator.
`
1258
1347
`///
`
1259
1348
`/// Note: this is an associated function, which means that you have
`