@@ -3,6 +3,7 @@ use crate::iter::{
3
3
} ;
4
4
use crate :: num:: NonZero ;
5
5
use crate :: range:: { Range , RangeFrom , RangeInclusive , legacy} ;
6
+ use crate :: { intrinsics, mem} ;
6
7
7
8
/// By-value [`Range`] iterator.
8
9
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
@@ -293,12 +294,25 @@ range_incl_exact_iter_impl! {
293
294
/// By-value [`RangeFrom`] iterator.
294
295
#[ unstable( feature = "new_range_api" , issue = "125687" ) ]
295
296
#[ derive( Debug , Clone ) ]
296
- pub struct IterRangeFrom < A > ( legacy:: RangeFrom < A > ) ;
297
+ pub struct IterRangeFrom < A > {
298
+ start : A ,
299
+ /// Whether the first element of the iterator has yielded.
300
+ /// Only used when overflow checks are enabled.
301
+ first : bool ,
302
+ }
297
303
298
- impl < A > IterRangeFrom < A > {
304
+ impl < A : Step > IterRangeFrom < A > {
299
305
/// Returns the remainder of the range being iterated over.
306
+ #[ inline]
307
+ #[ rustc_inherit_overflow_checks]
300
308
pub fn remainder ( self ) -> RangeFrom < A > {
301
- RangeFrom { start : self . 0 . start }
309
+ if intrinsics:: overflow_checks ( ) {
310
+ if !self . first {
311
+ return RangeFrom { start : Step :: forward ( self . start , 1 ) } ;
312
+ }
313
+ }
314
+
315
+ RangeFrom { start : self . start }
302
316
}
303
317
}
304
318
@@ -307,18 +321,47 @@ impl<A: Step> Iterator for IterRangeFrom<A> {
307
321
type Item = A ;
308
322
309
323
#[ inline]
324
+ #[ rustc_inherit_overflow_checks]
310
325
fn next ( & mut self ) -> Option < A > {
311
- self . 0 . next ( )
326
+ if intrinsics:: overflow_checks ( ) {
327
+ if self . first {
328
+ self . first = false ;
329
+ return Some ( self . start . clone ( ) ) ;
330
+ }
331
+
332
+ self . start = Step :: forward ( self . start . clone ( ) , 1 ) ;
333
+ return Some ( self . start . clone ( ) ) ;
334
+ }
335
+
336
+ let n = Step :: forward ( self . start . clone ( ) , 1 ) ;
337
+ Some ( mem:: replace ( & mut self . start , n) )
312
338
}
313
339
314
340
#[ inline]
315
341
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
316
- self . 0 . size_hint ( )
342
+ ( usize :: MAX , None )
317
343
}
318
344
319
345
#[ inline]
346
+ #[ rustc_inherit_overflow_checks]
320
347
fn nth ( & mut self , n : usize ) -> Option < A > {
321
- self . 0 . nth ( n)
348
+ if intrinsics:: overflow_checks ( ) {
349
+ if self . first {
350
+ self . first = false ;
351
+
352
+ let plus_n = Step :: forward ( self . start . clone ( ) , n) ;
353
+ self . start = plus_n. clone ( ) ;
354
+ return Some ( plus_n) ;
355
+ }
356
+
357
+ let plus_n = Step :: forward ( self . start . clone ( ) , n) ;
358
+ self . start = Step :: forward ( plus_n. clone ( ) , 1 ) ;
359
+ return Some ( self . start . clone ( ) ) ;
360
+ }
361
+
362
+ let plus_n = Step :: forward ( self . start . clone ( ) , n) ;
363
+ self . start = Step :: forward ( plus_n. clone ( ) , 1 ) ;
364
+ Some ( plus_n)
322
365
}
323
366
}
324
367
@@ -334,6 +377,6 @@ impl<A: Step> IntoIterator for RangeFrom<A> {
334
377
type IntoIter = IterRangeFrom < A > ;
335
378
336
379
fn into_iter ( self ) -> Self :: IntoIter {
337
- IterRangeFrom ( self . into ( ) )
380
+ IterRangeFrom { start : self . start , first : true }
338
381
}
339
382
}
0 commit comments