7575 }
7676}
7777
78- #[ inline( never) ]
79- #[ cold]
80- #[ track_caller]
81- const fn str_index_overflow_fail ( ) -> ! {
82- panic ! ( "attempted to index str up to maximum usize" ) ;
83- }
84-
8578/// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
8679///
8780/// Returns a slice of the whole string, i.e., returns `&self` or `&mut
@@ -639,11 +632,11 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
639632 type Output = str ;
640633 #[ inline]
641634 fn get ( self , slice : & str ) -> Option < & Self :: Output > {
642- if * self . end ( ) == usize :: MAX { None } else { self . into_slice_range ( ) . get ( slice) }
635+ if * self . end ( ) >= slice . len ( ) { None } else { self . into_slice_range ( ) . get ( slice) }
643636 }
644637 #[ inline]
645638 fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
646- if * self . end ( ) == usize :: MAX { None } else { self . into_slice_range ( ) . get_mut ( slice) }
639+ if * self . end ( ) >= slice . len ( ) { None } else { self . into_slice_range ( ) . get_mut ( slice) }
647640 }
648641 #[ inline]
649642 unsafe fn get_unchecked ( self , slice : * const str ) -> * const Self :: Output {
@@ -657,17 +650,37 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
657650 }
658651 #[ inline]
659652 fn index ( self , slice : & str ) -> & Self :: Output {
660- if * self . end ( ) == usize:: MAX {
661- str_index_overflow_fail ( ) ;
653+ let Self { mut start, mut end, exhausted } = self ;
654+ let len = slice. len ( ) ;
655+ if end < len {
656+ end = end + 1 ;
657+ start = if exhausted { end } else { start } ;
658+ if start <= end && slice. is_char_boundary ( start) && slice. is_char_boundary ( end) {
659+ // SAFETY: just checked that `start` and `end` are on a char boundary,
660+ // and we are passing in a safe reference, so the return value will also be one.
661+ // We also checked char boundaries, so this is valid UTF-8.
662+ unsafe { return & * ( start..end) . get_unchecked ( slice) } ;
663+ }
662664 }
663- self . into_slice_range ( ) . index ( slice)
665+
666+ super :: slice_error_fail ( slice, start, end) ;
664667 }
665668 #[ inline]
666669 fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
667- if * self . end ( ) == usize:: MAX {
668- str_index_overflow_fail ( ) ;
670+ let Self { mut start, mut end, exhausted } = self ;
671+ let len = slice. len ( ) ;
672+ if end < len {
673+ end = end + 1 ;
674+ start = if exhausted { end } else { start } ;
675+ if start <= end && slice. is_char_boundary ( start) && slice. is_char_boundary ( end) {
676+ // SAFETY: just checked that `start` and `end` are on a char boundary,
677+ // and we are passing in a safe reference, so the return value will also be one.
678+ // We also checked char boundaries, so this is valid UTF-8.
679+ unsafe { return & mut * ( start..end) . get_unchecked_mut ( slice) } ;
680+ }
669681 }
670- self . into_slice_range ( ) . index_mut ( slice)
682+
683+ super :: slice_error_fail ( slice, start, end) ;
671684 }
672685}
673686
@@ -677,35 +690,29 @@ unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
677690 type Output = str ;
678691 #[ inline]
679692 fn get ( self , slice : & str ) -> Option < & Self :: Output > {
680- if self . end == usize :: MAX { None } else { self . into_slice_range ( ) . get ( slice) }
693+ ops :: RangeInclusive :: from ( self ) . get ( slice)
681694 }
682695 #[ inline]
683696 fn get_mut ( self , slice : & mut str ) -> Option < & mut Self :: Output > {
684- if self . end == usize :: MAX { None } else { self . into_slice_range ( ) . get_mut ( slice) }
697+ ops :: RangeInclusive :: from ( self ) . get_mut ( slice)
685698 }
686699 #[ inline]
687700 unsafe fn get_unchecked ( self , slice : * const str ) -> * const Self :: Output {
688701 // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
689- unsafe { self . into_slice_range ( ) . get_unchecked ( slice) }
702+ unsafe { ops :: RangeInclusive :: from ( self ) . get_unchecked ( slice) }
690703 }
691704 #[ inline]
692705 unsafe fn get_unchecked_mut ( self , slice : * mut str ) -> * mut Self :: Output {
693706 // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
694- unsafe { self . into_slice_range ( ) . get_unchecked_mut ( slice) }
707+ unsafe { ops :: RangeInclusive :: from ( self ) . get_unchecked_mut ( slice) }
695708 }
696709 #[ inline]
697710 fn index ( self , slice : & str ) -> & Self :: Output {
698- if self . end == usize:: MAX {
699- str_index_overflow_fail ( ) ;
700- }
701- self . into_slice_range ( ) . index ( slice)
711+ ops:: RangeInclusive :: from ( self ) . index ( slice)
702712 }
703713 #[ inline]
704714 fn index_mut ( self , slice : & mut str ) -> & mut Self :: Output {
705- if self . end == usize:: MAX {
706- str_index_overflow_fail ( ) ;
707- }
708- self . into_slice_range ( ) . index_mut ( slice)
715+ ops:: RangeInclusive :: from ( self ) . index_mut ( slice)
709716 }
710717}
711718
0 commit comments