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