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