@@ -106,6 +106,10 @@ pub trait Iterator {
106
106
107
107
/// Counts the number of elements in this iterator.
108
108
///
109
+ /// # Panics
110
+ ///
111
+ /// Panics if the number of elements overflows a `usize`.
112
+ ///
109
113
/// # Examples
110
114
///
111
115
/// ```
@@ -115,7 +119,10 @@ pub trait Iterator {
115
119
#[ inline]
116
120
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
117
121
fn count ( self ) -> usize where Self : Sized {
118
- self . fold ( 0 , |cnt, _x| cnt + 1 )
122
+ self . fold ( 0 , |cnt, _| match cnt. checked_add ( 1 ) {
123
+ Some ( c) => c,
124
+ None => panic ! ( "overflow while counting the elements of an iterator" ) ,
125
+ } )
119
126
}
120
127
121
128
/// Loops through the entire iterator, returning the last element.
@@ -149,8 +156,10 @@ pub trait Iterator {
149
156
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
150
157
fn nth ( & mut self , mut n : usize ) -> Option < Self :: Item > where Self : Sized {
151
158
for x in self . by_ref ( ) {
152
- if n == 0 { return Some ( x) }
153
- n -= 1 ;
159
+ n = match n. checked_sub ( 1 ) {
160
+ Some ( nn) => nn,
161
+ None => return Some ( x) ,
162
+ }
154
163
}
155
164
None
156
165
}
@@ -277,6 +286,11 @@ pub trait Iterator {
277
286
/// `enumerate` keeps its count as a `usize`. If you want to count by a
278
287
/// different sized integer, the `zip` function provides similar functionality.
279
288
///
289
+ /// # Panics
290
+ ///
291
+ /// The returned iterator will panic if the to-be-returned index would
292
+ /// overflow a `usize`.
293
+ ///
280
294
/// # Examples
281
295
///
282
296
/// ```
@@ -289,7 +303,7 @@ pub trait Iterator {
289
303
#[ inline]
290
304
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
291
305
fn enumerate ( self ) -> Enumerate < Self > where Self : Sized {
292
- Enumerate { iter : self , count : 0 }
306
+ Enumerate { iter : self , count : Some ( 0 ) }
293
307
}
294
308
295
309
/// Creates an iterator that has a `.peek()` method
@@ -665,6 +679,11 @@ pub trait Iterator {
665
679
///
666
680
/// Does not consume the iterator past the first found element.
667
681
///
682
+ /// # Panics
683
+ ///
684
+ /// Panics if the number of elements overflows a `usize` and no matching
685
+ /// element was found until that point.
686
+ ///
668
687
/// # Examples
669
688
///
670
689
/// ```
@@ -684,7 +703,10 @@ pub trait Iterator {
684
703
if predicate ( x) {
685
704
return Some ( i) ;
686
705
}
687
- i += 1 ;
706
+ i = match i. checked_add ( 1 ) {
707
+ Some ( ii) => ii,
708
+ None => panic ! ( "overflow while getting the position of an element in an iterator" ) ,
709
+ }
688
710
}
689
711
None
690
712
}
@@ -715,6 +737,8 @@ pub trait Iterator {
715
737
if predicate ( v) {
716
738
return Some ( i - 1 ) ;
717
739
}
740
+ // No need for an overflow check here, because `ExactSizeIterator`
741
+ // implies that the number of elements fits into a `usize`.
718
742
i -= 1 ;
719
743
}
720
744
None
@@ -1761,19 +1785,26 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
1761
1785
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1762
1786
pub struct Enumerate < I > {
1763
1787
iter : I ,
1764
- count : usize
1788
+ count : Option < usize > ,
1765
1789
}
1766
1790
1767
1791
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1768
1792
impl < I > Iterator for Enumerate < I > where I : Iterator {
1769
1793
type Item = ( usize , <I as Iterator >:: Item ) ;
1770
1794
1795
+ /// # Panics
1796
+ ///
1797
+ /// Panics if the index of the element overflows a `usize`.
1771
1798
#[ inline]
1772
1799
fn next ( & mut self ) -> Option < ( usize , <I as Iterator >:: Item ) > {
1773
1800
match self . iter . next ( ) {
1774
1801
Some ( a) => {
1775
- let ret = Some ( ( self . count , a) ) ;
1776
- self . count += 1 ;
1802
+ let count = match self . count {
1803
+ Some ( c) => c,
1804
+ None => panic ! ( "overflow while enumerating an iterator" ) ,
1805
+ } ;
1806
+ let ret = Some ( ( count, a) ) ;
1807
+ self . count = count. checked_add ( 1 ) ;
1777
1808
ret
1778
1809
}
1779
1810
_ => None
@@ -1795,7 +1826,9 @@ impl<I> DoubleEndedIterator for Enumerate<I> where
1795
1826
match self . iter . next_back ( ) {
1796
1827
Some ( a) => {
1797
1828
let len = self . iter . len ( ) ;
1798
- Some ( ( self . count + len, a) )
1829
+ // Can safely `unwrap`, `ExactSizeIterator` promises that the
1830
+ // number of elements fits into a `usize`.
1831
+ Some ( ( self . count . unwrap ( ) + len, a) )
1799
1832
}
1800
1833
_ => None
1801
1834
}
@@ -1812,7 +1845,10 @@ impl<I> RandomAccessIterator for Enumerate<I> where I: RandomAccessIterator {
1812
1845
#[ inline]
1813
1846
fn idx ( & mut self , index : usize ) -> Option < ( usize , <I as Iterator >:: Item ) > {
1814
1847
match self . iter . idx ( index) {
1815
- Some ( a) => Some ( ( self . count + index, a) ) ,
1848
+ // Can safely `unwrap`, `ExactSizeIterator` (ancestor of
1849
+ // `RandomAccessIterator`) promises that the number of elements
1850
+ // fits into a `usize`.
1851
+ Some ( a) => Some ( ( self . count . unwrap ( ) + index, a) ) ,
1816
1852
_ => None ,
1817
1853
}
1818
1854
}
0 commit comments