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

`