@@ -1366,6 +1366,22 @@ impl<T> *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<T> *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<T> *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<T> *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
0 commit comments