@@ -1415,26 +1415,21 @@ impl<'a, T> Iterator for Windows<'a, T> {
14151415#[ stable( feature = "rust1" , since = "1.0.0" ) ]
14161416impl < ' a , T > DoubleEndedIterator for Windows < ' a , T > {
14171417 #[ inline]
1418- fn next_back ( & mut self ) -> Option < & ' a [ T ] > {
1419- if self . size . get ( ) > self . v . len ( ) {
1420- None
1421- } else {
1422- let ret = Some ( & self . v [ self . v . len ( ) - self . size . get ( ) ..] ) ;
1423- self . v = & self . v [ ..self . v . len ( ) - 1 ] ;
1424- ret
1425- }
1418+ fn next_back ( & mut self ) -> Option < Self :: Item > {
1419+ self . nth_back ( 0 )
14261420 }
14271421
14281422 #[ inline]
14291423 fn nth_back ( & mut self , n : usize ) -> Option < Self :: Item > {
1430- let ( end, overflow) = self . v . len ( ) . overflowing_sub ( n) ;
1431- if end < self . size . get ( ) || overflow {
1424+ if let Some ( end) = self . v . len ( ) . checked_sub ( n)
1425+ && let Some ( start) = end. checked_sub ( self . size . get ( ) )
1426+ {
1427+ let res = & self . v [ start..end] ;
1428+ self . v = & self . v [ ..end - 1 ] ;
1429+ Some ( res)
1430+ } else {
14321431 self . v = & self . v [ ..0 ] ; // cheaper than &[]
14331432 None
1434- } else {
1435- let ret = & self . v [ end - self . size . get ( ) ..end] ;
1436- self . v = & self . v [ ..end - 1 ] ;
1437- Some ( ret)
14381433 }
14391434 }
14401435}
@@ -1903,13 +1898,10 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19031898
19041899 #[ inline]
19051900 fn next ( & mut self ) -> Option < & ' a [ T ] > {
1906- if self . v . len ( ) < self . chunk_size {
1907- None
1908- } else {
1909- let ( fst, snd) = self . v . split_at ( self . chunk_size ) ;
1910- self . v = snd;
1911- Some ( fst)
1912- }
1901+ self . v . split_at_checked ( self . chunk_size ) . and_then ( |( chunk, rest) | {
1902+ self . v = rest;
1903+ Some ( chunk)
1904+ } )
19131905 }
19141906
19151907 #[ inline]
@@ -1925,14 +1917,14 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
19251917
19261918 #[ inline]
19271919 fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
1928- let ( start, overflow) = n. overflowing_mul ( self . chunk_size ) ;
1929- if start >= self . v . len ( ) || overflow {
1920+ if let Some ( start) = n. checked_mul ( self . chunk_size )
1921+ && start < self . v . len ( )
1922+ {
1923+ self . v = & self . v [ start..] ;
1924+ self . next ( )
1925+ } else {
19301926 self . v = & self . v [ ..0 ] ; // cheaper than &[]
19311927 None
1932- } else {
1933- let ( _, snd) = self . v . split_at ( start) ;
1934- self . v = snd;
1935- self . next ( )
19361928 }
19371929 }
19381930
@@ -2061,15 +2053,13 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20612053
20622054 #[ inline]
20632055 fn next ( & mut self ) -> Option < & ' a mut [ T ] > {
2064- if self . v . len ( ) < self . chunk_size {
2065- None
2066- } else {
2067- // SAFETY: self.chunk_size is inbounds because we compared above against self.v.len()
2068- let ( head, tail) = unsafe { self . v . split_at_mut ( self . chunk_size ) } ;
2069- self . v = tail;
2070- // SAFETY: Nothing else points to or will point to the contents of this slice.
2071- Some ( unsafe { & mut * head } )
2072- }
2056+ // SAFETY: we have `&mut self`, so are allowed to temporarily materialize a mut slice
2057+ unsafe { slice:: from_raw_parts_mut ( self . v , self . len ( ) ) }
2058+ . split_at_mut_checked ( self . chunk_size )
2059+ . and_then ( |( chunk, rest) | {
2060+ self . v = rest;
2061+ Some ( chunk)
2062+ } )
20732063 }
20742064
20752065 #[ inline]
@@ -2085,15 +2075,15 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20852075
20862076 #[ inline]
20872077 fn nth ( & mut self , n : usize ) -> Option < & ' a mut [ T ] > {
2088- let ( start, overflow) = n. overflowing_mul ( self . chunk_size ) ;
2089- if start >= self . v . len ( ) || overflow {
2090- self . v = & mut [ ] ;
2091- None
2092- } else {
2093- // SAFETY: The self.v contract ensures that any split_at_mut is valid.
2094- let ( _, snd) = unsafe { self . v . split_at_mut ( start) } ;
2095- self . v = snd;
2078+ if let Some ( start) = n. checked_mul ( self . chunk_size )
2079+ && start < self . v . len ( )
2080+ {
2081+ // SAFETY: `start < self.v.len()`
2082+ self . v = unsafe { self . v . split_at_mut ( start) . 1 } ;
20962083 self . next ( )
2084+ } else {
2085+ self . v = & self . v [ ..0 ] ; // cheaper than &[]
2086+ None
20972087 }
20982088 }
20992089
0 commit comments