@@ -382,16 +382,11 @@ impl<T> [T] {
382382 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
383383 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
384384 pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {
385- if self.len() < N {
386- None
387- } else {
388- // SAFETY: We manually verified the bounds of the split.
389- let (first, tail) = unsafe { self.split_at_unchecked(N) };
385+ let Some((first, tail)) = self.split_at_checked(N) else { return None };
390386
391- // SAFETY: We explicitly check for the correct number of elements,
392- // and do not let the references outlive the slice.
393- Some((unsafe { &*(first.as_ptr().cast::<[T; N]>()) }, tail))
394- }
387+ // SAFETY: We explicitly check for the correct number of elements,
388+ // and do not let the references outlive the slice.
389+ Some((unsafe { &*(first.as_ptr().cast::<[T; N]>()) }, tail))
395390 }
396391
397392 /// Returns a mutable array reference to the first `N` items in the slice and the remaining
@@ -419,17 +414,12 @@ impl<T> [T] {
419414 pub const fn split_first_chunk_mut<const N: usize>(
420415 &mut self,
421416 ) -> Option<(&mut [T; N], &mut [T])> {
422- if self.len() < N {
423- None
424- } else {
425- // SAFETY: We manually verified the bounds of the split.
426- let (first, tail) = unsafe { self.split_at_mut_unchecked(N) };
417+ let Some((first, tail)) = self.split_at_mut_checked(N) else { return None };
427418
428- // SAFETY: We explicitly check for the correct number of elements,
429- // do not let the reference outlive the slice,
430- // and enforce exclusive mutability of the chunk by the split.
431- Some((unsafe { &mut *(first.as_mut_ptr().cast::<[T; N]>()) }, tail))
432- }
419+ // SAFETY: We explicitly check for the correct number of elements,
420+ // do not let the reference outlive the slice,
421+ // and enforce exclusive mutability of the chunk by the split.
422+ Some((unsafe { &mut *(first.as_mut_ptr().cast::<[T; N]>()) }, tail))
433423 }
434424
435425 /// Returns an array reference to the last `N` items in the slice and the remaining slice.
@@ -452,16 +442,12 @@ impl<T> [T] {
452442 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
453443 #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
454444 pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])> {
455- if self.len() < N {
456- None
457- } else {
458- // SAFETY: We manually verified the bounds of the split.
459- let (init, last) = unsafe { self.split_at_unchecked(self.len() - N) };
445+ let Some(index) = self.len().checked_sub(N) else { return None };
446+ let (init, last) = self.split_at(index);
460447
461- // SAFETY: We explicitly check for the correct number of elements,
462- // and do not let the references outlive the slice.
463- Some((init, unsafe { &*(last.as_ptr().cast::<[T; N]>()) }))
464- }
448+ // SAFETY: We explicitly check for the correct number of elements,
449+ // and do not let the references outlive the slice.
450+ Some((init, unsafe { &*(last.as_ptr().cast::<[T; N]>()) }))
465451 }
466452
467453 /// Returns a mutable array reference to the last `N` items in the slice and the remaining
@@ -489,17 +475,13 @@ impl<T> [T] {
489475 pub const fn split_last_chunk_mut<const N: usize>(
490476 &mut self,
491477 ) -> Option<(&mut [T], &mut [T; N])> {
492- if self.len() < N {
493- None
494- } else {
495- // SAFETY: We manually verified the bounds of the split.
496- let (init, last) = unsafe { self.split_at_mut_unchecked(self.len() - N) };
478+ let Some(index) = self.len().checked_sub(N) else { return None };
479+ let (init, last) = self.split_at_mut(index);
497480
498- // SAFETY: We explicitly check for the correct number of elements,
499- // do not let the reference outlive the slice,
500- // and enforce exclusive mutability of the chunk by the split.
501- Some((init, unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) }))
502- }
481+ // SAFETY: We explicitly check for the correct number of elements,
482+ // do not let the reference outlive the slice,
483+ // and enforce exclusive mutability of the chunk by the split.
484+ Some((init, unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) }))
503485 }
504486
505487 /// Returns an array reference to the last `N` items in the slice.
@@ -522,17 +504,13 @@ impl<T> [T] {
522504 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
523505 #[rustc_const_stable(feature = "const_slice_last_chunk", since = "1.80.0")]
524506 pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]> {
525- if self.len() < N {
526- None
527- } else {
528- // SAFETY: We manually verified the bounds of the slice.
529- // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
530- let last = unsafe { self.split_at_unchecked(self.len() - N).1 };
507+ // FIXME(const-hack): Without const traits, we need this instead of `get`.
508+ let Some(index) = self.len().checked_sub(N) else { return None };
509+ let (_, last) = self.split_at(index);
531510
532- // SAFETY: We explicitly check for the correct number of elements,
533- // and do not let the references outlive the slice.
534- Some(unsafe { &*(last.as_ptr().cast::<[T; N]>()) })
535- }
511+ // SAFETY: We explicitly check for the correct number of elements,
512+ // and do not let the references outlive the slice.
513+ Some(unsafe { &*(last.as_ptr().cast::<[T; N]>()) })
536514 }
537515
538516 /// Returns a mutable array reference to the last `N` items in the slice.
@@ -556,18 +534,14 @@ impl<T> [T] {
556534 #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
557535 #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")]
558536 pub const fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
559- if self.len() < N {
560- None
561- } else {
562- // SAFETY: We manually verified the bounds of the slice.
563- // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
564- let last = unsafe { self.split_at_mut_unchecked(self.len() - N).1 };
565-
566- // SAFETY: We explicitly check for the correct number of elements,
567- // do not let the reference outlive the slice,
568- // and require exclusive access to the entire slice to mutate the chunk.
569- Some(unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) })
570- }
537+ // FIXME(const-hack): Without const traits, we need this instead of `get`.
538+ let Some(index) = self.len().checked_sub(N) else { return None };
539+ let (_, last) = self.split_at_mut(index);
540+
541+ // SAFETY: We explicitly check for the correct number of elements,
542+ // do not let the reference outlive the slice,
543+ // and require exclusive access to the entire slice to mutate the chunk.
544+ Some(unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) })
571545 }
572546
573547 /// Returns a reference to an element or subslice depending on the type of
0 commit comments