@@ -657,8 +657,25 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
657657 }
658658}
659659
660+ /// Return `Ok((start, new_len))` if the `RangeInclusive` is valid for a slice of
661+ /// length `len`, or `Err((start, end))` if it is not.
662+ #[ inline( always) ]
663+ const fn check_inclusive (
664+ range : ops:: RangeInclusive < usize > ,
665+ len : usize ,
666+ ) -> Result < ( usize , usize ) , ( usize , usize ) > {
667+ let ops:: RangeInclusive { mut start, mut end, exhausted } = range;
668+ if end < len {
669+ end = end + 1 ;
670+ start = if exhausted { end } else { start } ;
671+ if let Some ( new_len) = usize:: checked_sub ( end, start) {
672+ return Ok ( ( start, new_len) ) ;
673+ }
674+ }
675+ Err ( ( start, end) )
676+ }
677+
660678/// The methods `index` and `index_mut` panic if:
661- /// - the end of the range is `usize::MAX` or
662679/// - the start of the range is greater than the end of the range or
663680/// - the end of the range is out of bounds.
664681#[ stable( feature = "inclusive_range" , since = "1.26.0" ) ]
@@ -668,12 +685,24 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
668685
669686 #[ inline]
670687 fn get ( self , slice : & [ T ] ) -> Option < & [ T ] > {
671- if * self . end ( ) == usize:: MAX { None } else { self . into_slice_range ( ) . get ( slice) }
688+ match check_inclusive ( self , slice. len ( ) ) {
689+ Ok ( ( start, new_len) ) => {
690+ // SAFETY: We checked that the range is valid above.
691+ unsafe { Some ( & * get_offset_len_noubcheck ( slice, start, new_len) ) }
692+ }
693+ Err ( _) => None ,
694+ }
672695 }
673696
674697 #[ inline]
675698 fn get_mut ( self , slice : & mut [ T ] ) -> Option < & mut [ T ] > {
676- if * self . end ( ) == usize:: MAX { None } else { self . into_slice_range ( ) . get_mut ( slice) }
699+ match check_inclusive ( self , slice. len ( ) ) {
700+ Ok ( ( start, new_len) ) => {
701+ // SAFETY: We checked that the range is valid above.
702+ unsafe { Some ( & mut * get_offset_len_mut_noubcheck ( slice, start, new_len) ) }
703+ }
704+ Err ( _) => None ,
705+ }
677706 }
678707
679708 #[ inline]
@@ -690,32 +719,24 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
690719
691720 #[ inline]
692721 fn index ( self , slice : & [ T ] ) -> & [ T ] {
693- let Self { mut start, mut end, exhausted } = self ;
694- let len = slice. len ( ) ;
695- if end < len {
696- end = end + 1 ;
697- start = if exhausted { end } else { start } ;
698- if let Some ( new_len) = usize:: checked_sub ( end, start) {
699- // SAFETY: `self` is checked to be valid and in bounds above.
700- unsafe { return & * get_offset_len_noubcheck ( slice, start, new_len) }
722+ match check_inclusive ( self , slice. len ( ) ) {
723+ Ok ( ( start, new_len) ) => {
724+ // SAFETY: We checked that the range is valid above.
725+ unsafe { & * get_offset_len_noubcheck ( slice, start, new_len) }
701726 }
727+ Err ( ( start, end) ) => slice_index_fail ( start, end, slice. len ( ) ) ,
702728 }
703- slice_index_fail ( start, end, slice. len ( ) )
704729 }
705730
706731 #[ inline]
707732 fn index_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
708- let Self { mut start, mut end, exhausted } = self ;
709- let len = slice. len ( ) ;
710- if end < len {
711- end = end + 1 ;
712- start = if exhausted { end } else { start } ;
713- if let Some ( new_len) = usize:: checked_sub ( end, start) {
714- // SAFETY: `self` is checked to be valid and in bounds above.
715- unsafe { return & mut * get_offset_len_mut_noubcheck ( slice, start, new_len) }
733+ match check_inclusive ( self , slice. len ( ) ) {
734+ Ok ( ( start, new_len) ) => {
735+ // SAFETY: We checked that the range is valid above.
736+ unsafe { & mut * get_offset_len_mut_noubcheck ( slice, start, new_len) }
716737 }
738+ Err ( ( start, end) ) => slice_index_fail ( start, end, slice. len ( ) ) ,
717739 }
718- slice_index_fail ( start, end, slice. len ( ) )
719740 }
720741}
721742
0 commit comments