@@ -171,6 +171,79 @@ fn test_iterator_step_by_zero() {
171171 it. next ( ) ;
172172}
173173
174+ #[ test]
175+ fn test_iterator_step_by_size_hint ( ) {
176+ struct StubSizeHint ( usize , Option < usize > ) ;
177+ impl Iterator for StubSizeHint {
178+ type Item = ( ) ;
179+ fn next ( & mut self ) -> Option < ( ) > {
180+ self . 0 -= 1 ;
181+ if let Some ( ref mut upper) = self . 1 {
182+ * upper -= 1 ;
183+ }
184+ Some ( ( ) )
185+ }
186+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
187+ ( self . 0 , self . 1 )
188+ }
189+ }
190+
191+ // The two checks in each case are needed because the logic
192+ // is different before the first call to `next()`.
193+
194+ let mut it = StubSizeHint ( 10 , Some ( 10 ) ) . step_by ( 1 ) ;
195+ assert_eq ! ( it. size_hint( ) , ( 10 , Some ( 10 ) ) ) ;
196+ it. next ( ) ;
197+ assert_eq ! ( it. size_hint( ) , ( 9 , Some ( 9 ) ) ) ;
198+
199+ // exact multiple
200+ let mut it = StubSizeHint ( 10 , Some ( 10 ) ) . step_by ( 3 ) ;
201+ assert_eq ! ( it. size_hint( ) , ( 4 , Some ( 4 ) ) ) ;
202+ it. next ( ) ;
203+ assert_eq ! ( it. size_hint( ) , ( 3 , Some ( 3 ) ) ) ;
204+
205+ // larger base range, but not enough to get another element
206+ let mut it = StubSizeHint ( 12 , Some ( 12 ) ) . step_by ( 3 ) ;
207+ assert_eq ! ( it. size_hint( ) , ( 4 , Some ( 4 ) ) ) ;
208+ it. next ( ) ;
209+ assert_eq ! ( it. size_hint( ) , ( 3 , Some ( 3 ) ) ) ;
210+
211+ // smaller base range, so fewer resulting elements
212+ let mut it = StubSizeHint ( 9 , Some ( 9 ) ) . step_by ( 3 ) ;
213+ assert_eq ! ( it. size_hint( ) , ( 3 , Some ( 3 ) ) ) ;
214+ it. next ( ) ;
215+ assert_eq ! ( it. size_hint( ) , ( 2 , Some ( 2 ) ) ) ;
216+
217+ // infinite upper bound
218+ let mut it = StubSizeHint ( usize:: MAX , None ) . step_by ( 1 ) ;
219+ assert_eq ! ( it. size_hint( ) , ( usize :: MAX , None ) ) ;
220+ it. next ( ) ;
221+ assert_eq ! ( it. size_hint( ) , ( usize :: MAX -1 , None ) ) ;
222+
223+ // still infinite with larger step
224+ let mut it = StubSizeHint ( 7 , None ) . step_by ( 3 ) ;
225+ assert_eq ! ( it. size_hint( ) , ( 3 , None ) ) ;
226+ it. next ( ) ;
227+ assert_eq ! ( it. size_hint( ) , ( 2 , None ) ) ;
228+
229+ // propagates ExactSizeIterator
230+ let a = [ 1 , 2 , 3 , 4 , 5 ] ;
231+ let it = a. iter ( ) . step_by ( 2 ) ;
232+ assert_eq ! ( it. len( ) , 3 ) ;
233+
234+ // Cannot be TrustedLen as a step greater than one makes an iterator
235+ // with (usize::MAX, None) no longer meet the safety requirements
236+ trait TrustedLenCheck { fn test ( self ) -> bool ; }
237+ impl < T : Iterator > TrustedLenCheck for T {
238+ default fn test ( self ) -> bool { false }
239+ }
240+ impl < T : TrustedLen > TrustedLenCheck for T {
241+ fn test ( self ) -> bool { true }
242+ }
243+ assert ! ( TrustedLenCheck :: test( a. iter( ) ) ) ;
244+ assert ! ( !TrustedLenCheck :: test( a. iter( ) . step_by( 1 ) ) ) ;
245+ }
246+
174247#[ test]
175248fn test_filter_map ( ) {
176249 let it = ( 0 ..) . step_by ( 1 ) . take ( 10 )
0 commit comments