@@ -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