7676 }
7777}
7878
79- #[ inline( never) ]
80- #[ cold]
81- #[ track_caller]
82- const fn str_index_overflow_fail ( ) -> ! {
83- panic ! ( "attempted to index str up to maximum usize" ) ;
84- }
85-
8679/// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
8780///
8881/// Returns a slice of the whole string, i.e., returns `&self` or `&mut
@@ -640,11 +633,11 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
640633 type Output = str ;
641634 #[ inline]
642635 fn get ( self , slice : & str ) -> Option < & Self :: Output > {
643- if * self . end ( ) == usize :: MAX { None } else { self . into_slice_range ( ) . get ( slice) }
636+ if * self . end ( ) >= slice . len ( ) { None } else { self . into_slice_range ( ) . get ( slice) }
644637 }
645638 #[ inline]
646639 fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
647- if * self . end ( ) == usize :: MAX { None } else { self . into_slice_range ( ) . get_mut ( slice) }
640+ if * self . end ( ) >= slice . len ( ) { None } else { self . into_slice_range ( ) . get_mut ( slice) }
648641 }
649642 #[ inline]
650643 unsafe fn get_unchecked ( self , slice : * const str ) -> * const Self :: Output {
@@ -658,17 +651,37 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
658651 }
659652 #[ inline]
660653 fn index ( self , slice : & str ) -> & Self :: Output {
661- if * self . end ( ) == usize:: MAX {
662- str_index_overflow_fail ( ) ;
654+ let Self { mut start, mut end, exhausted } = self ;
655+ let len = slice. len ( ) ;
656+ if end < len {
657+ end = end + 1 ;
658+ start = if exhausted { end } else { start } ;
659+ if start <= end && slice. is_char_boundary ( start) && slice. is_char_boundary ( end) {
660+ // SAFETY: just checked that `start` and `end` are on a char boundary,
661+ // and we are passing in a safe reference, so the return value will also be one.
662+ // We also checked char boundaries, so this is valid UTF-8.
663+ unsafe { return & * ( start..end) . get_unchecked ( slice) } ;
664+ }
663665 }
664- self . into_slice_range ( ) . index ( slice)
666+
667+ super :: slice_error_fail ( slice, start, end) ;
665668 }
666669 #[ inline]
667670 fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
668- if * self . end ( ) == usize:: MAX {
669- str_index_overflow_fail ( ) ;
671+ let Self { mut start, mut end, exhausted } = self ;
672+ let len = slice. len ( ) ;
673+ if end < len {
674+ end = end + 1 ;
675+ start = if exhausted { end } else { start } ;
676+ if start <= end && slice. is_char_boundary ( start) && slice. is_char_boundary ( end) {
677+ // SAFETY: just checked that `start` and `end` are on a char boundary,
678+ // and we are passing in a safe reference, so the return value will also be one.
679+ // We also checked char boundaries, so this is valid UTF-8.
680+ unsafe { return & mut * ( start..end) . get_unchecked_mut ( slice) } ;
681+ }
670682 }
671- self . into_slice_range ( ) . index_mut ( slice)
683+
684+ super :: slice_error_fail ( slice, start, end) ;
672685 }
673686}
674687
@@ -678,35 +691,29 @@ unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
678691 type Output = str ;
679692 #[ inline]
680693 fn get ( self , slice : & str ) -> Option < & Self :: Output > {
681- if self . last == usize :: MAX { None } else { self . into_slice_range ( ) . get ( slice) }
694+ ops :: RangeInclusive :: from ( self ) . get ( slice)
682695 }
683696 #[ inline]
684697 fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
685- if self . last == usize :: MAX { None } else { self . into_slice_range ( ) . get_mut ( slice) }
698+ ops :: RangeInclusive :: from ( self ) . get_mut ( slice)
686699 }
687700 #[ inline]
688701 unsafe fn get_unchecked ( self , slice : * const str ) -> * const Self :: Output {
689702 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
690- unsafe { self . into_slice_range ( ) . get_unchecked ( slice) }
703+ unsafe { ops :: RangeInclusive :: from ( self ) . get_unchecked ( slice) }
691704 }
692705 #[ inline]
693706 unsafe fn get_unchecked_mut ( self , slice : * mut str ) -> * mut Self :: Output {
694707 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
695- unsafe { self . into_slice_range ( ) . get_unchecked_mut ( slice) }
708+ unsafe { ops :: RangeInclusive :: from ( self ) . get_unchecked_mut ( slice) }
696709 }
697710 #[ inline]
698711 fn index ( self , slice : & str ) -> & Self :: Output {
699- if self . last == usize:: MAX {
700- str_index_overflow_fail ( ) ;
701- }
702- self . into_slice_range ( ) . index ( slice)
712+ ops:: RangeInclusive :: from ( self ) . index ( slice)
703713 }
704714 #[ inline]
705715 fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
706- if self . last == usize:: MAX {
707- str_index_overflow_fail ( ) ;
708- }
709- self . into_slice_range ( ) . index_mut ( slice)
716+ ops:: RangeInclusive :: from ( self ) . index_mut ( slice)
710717 }
711718}
712719
0 commit comments