@@ -1705,6 +1705,13 @@ pub trait StrSlice<'a> {
1705
1705
fn utf16_units ( & self ) -> Utf16CodeUnits < ' a > ;
1706
1706
}
1707
1707
1708
+ #[ inline( never) ]
1709
+ fn slice_error_fail ( s : & str , begin : uint , end : uint ) -> ! {
1710
+ assert ! ( begin <= end) ;
1711
+ fail ! ( "index {} and/or {} in `{}` do not lie on character boundary" ,
1712
+ begin, end, s) ;
1713
+ }
1714
+
1708
1715
impl < ' a > StrSlice < ' a > for & ' a str {
1709
1716
#[ inline]
1710
1717
fn contains < ' a > ( & self , needle : & ' a str ) -> bool {
@@ -1808,22 +1815,34 @@ impl<'a> StrSlice<'a> for &'a str {
1808
1815
1809
1816
#[ inline]
1810
1817
fn slice ( & self , begin : uint , end : uint ) -> & ' a str {
1811
- assert ! ( self . is_char_boundary( begin) && self . is_char_boundary( end) ,
1812
- "index {} and/or {} in `{}` do not lie on character boundary" , begin,
1813
- end, * self ) ;
1814
- unsafe { raw:: slice_bytes ( * self , begin, end) }
1818
+ // is_char_boundary checks that the index is in [0, .len()]
1819
+ if begin <= end &&
1820
+ self . is_char_boundary ( begin) &&
1821
+ self . is_char_boundary ( end) {
1822
+ unsafe { raw:: slice_unchecked ( * self , begin, end) }
1823
+ } else {
1824
+ slice_error_fail ( * self , begin, end)
1825
+ }
1815
1826
}
1816
1827
1817
1828
#[ inline]
1818
1829
fn slice_from ( & self , begin : uint ) -> & ' a str {
1819
- self . slice ( begin, self . len ( ) )
1830
+ // is_char_boundary checks that the index is in [0, .len()]
1831
+ if self . is_char_boundary ( begin) {
1832
+ unsafe { raw:: slice_unchecked ( * self , begin, self . len ( ) ) }
1833
+ } else {
1834
+ slice_error_fail ( * self , begin, self . len ( ) )
1835
+ }
1820
1836
}
1821
1837
1822
1838
#[ inline]
1823
1839
fn slice_to ( & self , end : uint ) -> & ' a str {
1824
- assert ! ( self . is_char_boundary( end) , "index {} in `{}` does not lie on \
1825
- a character boundary", end, * self ) ;
1826
- unsafe { raw:: slice_bytes ( * self , 0 , end) }
1840
+ // is_char_boundary checks that the index is in [0, .len()]
1841
+ if self . is_char_boundary ( end) {
1842
+ unsafe { raw:: slice_unchecked ( * self , 0 , end) }
1843
+ } else {
1844
+ slice_error_fail ( * self , 0 , end)
1845
+ }
1827
1846
}
1828
1847
1829
1848
fn slice_chars ( & self , begin : uint , end : uint ) -> & ' a str {
@@ -1898,9 +1917,10 @@ impl<'a> StrSlice<'a> for &'a str {
1898
1917
#[ inline]
1899
1918
fn is_char_boundary ( & self , index : uint ) -> bool {
1900
1919
if index == self . len ( ) { return true ; }
1901
- if index > self . len ( ) { return false ; }
1902
- let b = self . as_bytes ( ) [ index] ;
1903
- return b < 128u8 || b >= 192u8 ;
1920
+ match self . as_bytes ( ) . get ( index) {
1921
+ None => false ,
1922
+ Some ( & b) => b < 128u8 || b >= 192u8 ,
1923
+ }
1904
1924
}
1905
1925
1906
1926
#[ inline]
0 commit comments