@@ -1366,6 +1366,22 @@ impl<T> *mut [T] {
13661366 ///
13671367 /// Panics if `mid > len`.
13681368 ///
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+ ///
13691385 /// # Examples
13701386 ///
13711387 /// ```
@@ -1374,19 +1390,19 @@ impl<T> *mut [T] {
13741390 ///
13751391 /// let mut v = [1, 0, 3, 0, 5, 6];
13761392 /// let ptr = &mut v as *mut [_];
1377- /// let (left, right) = ptr.split_at_mut(2);
13781393 /// unsafe {
1394+ /// let (left, right) = ptr.split_at_mut(2);
13791395 /// assert_eq!(&*left, [1, 0]);
13801396 /// assert_eq!(&*right, [3, 0, 5, 6]);
13811397 /// }
13821398 /// ```
13831399 #[ inline( always) ]
13841400 #[ track_caller]
13851401 #[ 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 ] ) {
13871403 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`
13901406 unsafe { self . split_at_mut_unchecked ( mid) }
13911407 }
13921408
@@ -1396,16 +1412,15 @@ impl<T> *mut [T] {
13961412 /// the index `mid` itself) and the second will contain all
13971413 /// indices from `[mid, len)` (excluding the index `len` itself).
13981414 ///
1399- /// For a safe alternative see [`split_at_mut`].
1400- ///
1401- /// [`split_at_mut`]: #method.split_at_mut
1402- ///
14031415 /// # Safety
14041416 ///
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.
14081421 ///
1422+ /// [in-bounds]: #method.add
1423+ /// [out-of-bounds index]: #method.add
14091424 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
14101425 ///
14111426 /// # Examples
@@ -1431,16 +1446,12 @@ impl<T> *mut [T] {
14311446 let len = self . len ( ) ;
14321447 let ptr = self . as_mut_ptr ( ) ;
14331448
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+ )
14441455 }
14451456
14461457 /// Returns a raw pointer to the slice's buffer.
@@ -1466,9 +1477,10 @@ impl<T> *mut [T] {
14661477 /// Returns a raw pointer to an element or subslice, without doing bounds
14671478 /// checking.
14681479 ///
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
14701481 /// is *[undefined behavior]* even if the resulting pointer is not used.
14711482 ///
1483+ /// [out-of-bounds index]: #method.add
14721484 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
14731485 ///
14741486 /// # Examples
0 commit comments