Update safety comments, make split_at_mut
unsafe · rust-lang/rust@b0ca46e (original) (raw)
`@@ -1366,6 +1366,22 @@ impl *mut [T] {
`
1366
1366
`///
`
1367
1367
`` /// Panics if mid > len
.
``
1368
1368
`///
`
``
1369
`+
/// # Safety
`
``
1370
`+
///
`
``
1371
`` +
/// mid
must be [in-bounds] of the underlying [allocated object].
``
``
1372
`` +
/// Which means self
must be dereferenceable and span a single allocation
``
``
1373
`` +
/// that is at least mid * size_of::<T>()
bytes long. Not upholding these
``
``
1374
`+
/// requirements is [undefined behavior] even if the resulting pointers are not used.
`
``
1375
`+
///
`
``
1376
`` +
/// Since len
being in-bounds it is not a safety invariant of *mut [T]
the
``
``
1377
`` +
/// safety requirements of this method are the same as for [split_at_mut_unchecked
].
``
``
1378
`` +
/// The explicit bounds check is only as useful as len
is correct.
``
``
1379
`+
///
`
``
1380
`` +
/// [split_at_mut_unchecked
]: #method.split_at_mut_unchecked
``
``
1381
`+
/// [in-bounds]: #method.add
`
``
1382
`+
/// [allocated object]: crate::ptr#allocated-object
`
``
1383
`+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
`
``
1384
`+
///
`
1369
1385
`/// # Examples
`
1370
1386
`///
`
1371
1387
```` /// ```
`@@ -1374,19 +1390,19 @@ impl<T> *mut [T] {
`
`1374`
`1390`
`///
`
`1375`
`1391`
`/// let mut v = [1, 0, 3, 0, 5, 6];
`
`1376`
`1392`
`/// let ptr = &mut v as *mut [_];
`
`1377`
``
`-
/// let (left, right) = ptr.split_at_mut(2);
`
`1378`
`1393`
`/// unsafe {
`
``
`1394`
`+
/// let (left, right) = ptr.split_at_mut(2);
`
`1379`
`1395`
`/// assert_eq!(&*left, [1, 0]);
`
`1380`
`1396`
`/// assert_eq!(&*right, [3, 0, 5, 6]);
`
`1381`
`1397`
`/// }
`
`1382`
`1398`
```` /// ```
1383
1399
`#[inline(always)]
`
1384
1400
`#[track_caller]
`
1385
1401
`#[unstable(feature = "raw_slice_split", issue = "95595")]
`
1386
``
`-
pub fn split_at_mut(self, mid: usize) -> (*mut [T], *mut [T]) {
`
``
1402
`+
pub unsafe fn split_at_mut(self, mid: usize) -> (*mut [T], *mut [T]) {
`
1387
1403
`assert!(mid <= self.len());
`
1388
``
`` -
// SAFETY: [ptr; mid]
and [mid; len]
are inside self
, which
``
1389
``
`` -
// fulfills the requirements of from_raw_parts_mut
.
``
``
1404
`` +
// SAFETY: The assert above is only a safety-net as long as self.len()
is correct
``
``
1405
`` +
// The actual safety requirements of this function are the same as for split_at_mut_unchecked
``
1390
1406
`unsafe { self.split_at_mut_unchecked(mid) }
`
1391
1407
`}
`
1392
1408
``
`@@ -1396,16 +1412,15 @@ impl *mut [T] {
`
1396
1412
`` /// the index mid
itself) and the second will contain all
``
1397
1413
`` /// indices from [mid, len)
(excluding the index len
itself).
``
1398
1414
`///
`
1399
``
`` -
/// For a safe alternative see [split_at_mut
].
``
1400
``
`-
///
`
1401
``
`` -
/// [split_at_mut
]: #method.split_at_mut
``
1402
``
`-
///
`
1403
1415
`/// # Safety
`
1404
1416
`///
`
1405
``
`-
/// Calling this method with an out-of-bounds index is [undefined behavior]
`
1406
``
`-
/// even if the resulting reference is not used. The caller has to ensure that
`
1407
``
`` -
/// 0 <= mid <= self.len()
.
``
``
1417
`` +
/// mid
must be [in-bounds] of the underlying [allocated object].
``
``
1418
`` +
/// Which means self
must be dereferenceable and span a single allocation
``
``
1419
`` +
/// that is at least mid * size_of::<T>()
bytes long. Not upholding these
``
``
1420
`+
/// requirements is [undefined behavior] even if the resulting pointers are not used.
`
1408
1421
`///
`
``
1422
`+
/// [in-bounds]: #method.add
`
``
1423
`+
/// [out-of-bounds index]: #method.add
`
1409
1424
`/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
`
1410
1425
`///
`
1411
1426
`/// # Examples
`
`@@ -1431,16 +1446,12 @@ impl *mut [T] {
`
1431
1446
`let len = self.len();
`
1432
1447
`let ptr = self.as_mut_ptr();
`
1433
1448
``
1434
``
`` -
// SAFETY: Caller has to check that 0 <= mid <= self.len()
.
``
1435
``
`-
//
`
1436
``
`` -
// [ptr; mid]
and [mid; len]
are not overlapping, so returning a mutable reference
``
1437
``
`-
// is fine.
`
1438
``
`-
unsafe {
`
1439
``
`-
(
`
1440
``
`-
crate::ptr::slice_from_raw_parts_mut(ptr, mid),
`
1441
``
`-
crate::ptr::slice_from_raw_parts_mut(ptr.add(mid), len - mid),
`
1442
``
`-
)
`
1443
``
`-
}
`
``
1449
`+
// SAFETY: Caller must pass a valid pointer and an index that is in-bounds.
`
``
1450
`+
let tail = unsafe { ptr.add(mid) };
`
``
1451
`+
(
`
``
1452
`+
crate::ptr::slice_from_raw_parts_mut(ptr, mid),
`
``
1453
`+
crate::ptr::slice_from_raw_parts_mut(tail, len - mid),
`
``
1454
`+
)
`
1444
1455
`}
`
1445
1456
``
1446
1457
`/// Returns a raw pointer to the slice's buffer.
`
`@@ -1466,9 +1477,10 @@ impl *mut [T] {
`
1466
1477
`/// Returns a raw pointer to an element or subslice, without doing bounds
`
1467
1478
`/// checking.
`
1468
1479
`///
`
1469
``
`` -
/// Calling this method with an out-of-bounds index or when self
is not dereferenceable
``
``
1480
`` +
/// Calling this method with an [out-of-bounds index] or when self
is not dereferenceable
``
1470
1481
`/// is [undefined behavior] even if the resulting pointer is not used.
`
1471
1482
`///
`
``
1483
`+
/// [out-of-bounds index]: #method.add
`
1472
1484
`/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
`
1473
1485
`///
`
1474
1486
`/// # Examples
`