@@ -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
}
@@ -280,6 +289,16 @@ pub trait Iterator {
280
289
/// different sized integer, the `zip` function provides similar
281
290
/// functionality.
282
291
///
292
+ /// # Undefined overflow
293
+ ///
294
+ /// The method does no guarding against overflows, so enumerating more than
295
+ /// `usize::MAX` elements is undefined.
296
+ ///
297
+ /// # Panics
298
+ ///
299
+ /// The returned iterator might panic if the to-be-returned index would
300
+ /// overflow a `usize`.
301
+ ///
283
302
/// # Examples
284
303
///
285
304
/// ```
@@ -292,7 +311,7 @@ pub trait Iterator {
292
311
#[ inline]
293
312
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
294
313
fn enumerate ( self ) -> Enumerate < Self > where Self : Sized {
295
- Enumerate { iter : self , count : 0 }
314
+ Enumerate { iter : self , count : 0 }
296
315
}
297
316
298
317
/// Creates an iterator that has a `.peek()` method
@@ -674,6 +693,11 @@ pub trait Iterator {
674
693
///
675
694
/// Does not consume the iterator past the first found element.
676
695
///
696
+ /// # Panics
697
+ ///
698
+ /// Panics if the number of elements overflows a `usize` and no matching
699
+ /// element was found until that point.
700
+ ///
677
701
/// # Examples
678
702
///
679
703
/// ```
@@ -693,7 +717,10 @@ pub trait Iterator {
693
717
if predicate ( x) {
694
718
return Some ( i) ;
695
719
}
696
- i += 1 ;
720
+ i = match i. checked_add ( 1 ) {
721
+ Some ( ii) => ii,
722
+ None => panic ! ( "overflow while getting the position of an element in an iterator" ) ,
723
+ }
697
724
}
698
725
None
699
726
}
@@ -724,6 +751,8 @@ pub trait Iterator {
724
751
if predicate ( v) {
725
752
return Some ( i - 1 ) ;
726
753
}
754
+ // No need for an overflow check here, because `ExactSizeIterator`
755
+ // implies that the number of elements fits into a `usize`.
727
756
i -= 1 ;
728
757
}
729
758
None
@@ -1761,17 +1790,27 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
1761
1790
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1762
1791
pub struct Enumerate < I > {
1763
1792
iter : I ,
1764
- count : usize
1793
+ count : usize ,
1765
1794
}
1766
1795
1767
1796
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1768
1797
impl < I > Iterator for Enumerate < I > where I : Iterator {
1769
1798
type Item = ( usize , <I as Iterator >:: Item ) ;
1770
1799
1800
+
1801
+ /// # Undefined overflow
1802
+ ///
1803
+ /// The method does no guarding against overflows, so enumerating more than
1804
+ /// `usize::MAX` elements is undefined.
1805
+ ///
1806
+ /// # Panics
1807
+ ///
1808
+ /// Might panic if the index of the element overflows a `usize`.
1771
1809
#[ inline]
1772
1810
fn next ( & mut self ) -> Option < ( usize , <I as Iterator >:: Item ) > {
1773
1811
self . iter . next ( ) . map ( |a| {
1774
1812
let ret = ( self . count , a) ;
1813
+ // Possible undefined overflow.
1775
1814
self . count += 1 ;
1776
1815
ret
1777
1816
} )
@@ -1791,6 +1830,8 @@ impl<I> DoubleEndedIterator for Enumerate<I> where
1791
1830
fn next_back ( & mut self ) -> Option < ( usize , <I as Iterator >:: Item ) > {
1792
1831
self . iter . next_back ( ) . map ( |a| {
1793
1832
let len = self . iter . len ( ) ;
1833
+ // Can safely add, `ExactSizeIterator` promises that the number of
1834
+ // elements fits into a `usize`.
1794
1835
( self . count + len, a)
1795
1836
} )
1796
1837
}
@@ -1805,6 +1846,9 @@ impl<I> RandomAccessIterator for Enumerate<I> where I: RandomAccessIterator {
1805
1846
1806
1847
#[ inline]
1807
1848
fn idx ( & mut self , index : usize ) -> Option < ( usize , <I as Iterator >:: Item ) > {
1849
+ // Can safely add, `ExactSizeIterator` (ancestor of
1850
+ // `RandomAccessIterator`) promises that the number of elements fits
1851
+ // into a `usize`.
1808
1852
self . iter . idx ( index) . map ( |a| ( self . count + index, a) )
1809
1853
}
1810
1854
}
0 commit comments