76
76
}
77
77
}
78
78
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
-
86
79
/// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
87
80
///
88
81
/// 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> {
640
633
type Output = str ;
641
634
#[ inline]
642
635
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) }
644
637
}
645
638
#[ inline]
646
639
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) }
648
641
}
649
642
#[ inline]
650
643
unsafe fn get_unchecked ( self , slice : * const str ) -> * const Self :: Output {
@@ -658,17 +651,37 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
658
651
}
659
652
#[ inline]
660
653
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
+ }
663
665
}
664
- self . into_slice_range ( ) . index ( slice)
666
+
667
+ super :: slice_error_fail ( slice, start, end) ;
665
668
}
666
669
#[ inline]
667
670
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
+ }
670
682
}
671
- self . into_slice_range ( ) . index_mut ( slice)
683
+
684
+ super :: slice_error_fail ( slice, start, end) ;
672
685
}
673
686
}
674
687
@@ -678,35 +691,29 @@ unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
678
691
type Output = str ;
679
692
#[ inline]
680
693
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)
682
695
}
683
696
#[ inline]
684
697
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)
686
699
}
687
700
#[ inline]
688
701
unsafe fn get_unchecked ( self , slice : * const str ) -> * const Self :: Output {
689
702
// 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) }
691
704
}
692
705
#[ inline]
693
706
unsafe fn get_unchecked_mut ( self , slice : * mut str ) -> * mut Self :: Output {
694
707
// 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) }
696
709
}
697
710
#[ inline]
698
711
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)
703
713
}
704
714
#[ inline]
705
715
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)
710
717
}
711
718
}
712
719
0 commit comments