diff --git a/library/core/src/iter/adapters/step_by.rs b/library/core/src/iter/adapters/step_by.rs index 4c70c9dc84b3b..6b4757a1cb871 100644 --- a/library/core/src/iter/adapters/step_by.rs +++ b/library/core/src/iter/adapters/step_by.rs @@ -1,5 +1,5 @@ use crate::intrinsics; -use crate::iter::{TrustedLen, TrustedRandomAccess, from_fn}; +use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, from_fn}; use crate::num::NonZero; use crate::ops::{Range, Try}; use crate::range::RangeIter; @@ -136,6 +136,11 @@ where #[stable(feature = "iterator_step_by", since = "1.28.0")] impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} +// StepBy can be marked as a `FusedIterator` if the underlying iterator +// is fused +#[stable(feature = "fuse_step_by", since = "CURRENT_RUSTC_VERSION")] +impl FusedIterator for StepBy where I: FusedIterator {} + // SAFETY: This adapter is shortening. TrustedLen requires the upper bound to be calculated correctly. // These requirements can only be satisfied when the upper bound of the inner iterator's upper // bound is never `None`. I: TrustedRandomAccess happens to provide this guarantee while diff --git a/library/coretests/tests/iter/adapters/step_by.rs b/library/coretests/tests/iter/adapters/step_by.rs index 1ebebb9691933..30810a29883dd 100644 --- a/library/coretests/tests/iter/adapters/step_by.rs +++ b/library/coretests/tests/iter/adapters/step_by.rs @@ -337,3 +337,25 @@ fn test_step_by_new_range_iter() { assert_eq!(it.next_back(), Some(10)); assert_eq!(it.next(), None); } + +#[test] +fn test_step_by_fused_iterator() { + struct TestFusedIter(usize); + impl Iterator for TestFusedIter { + type Item = usize; + fn next(&mut self) -> Option { + if self.0 > 5 { + let ret = self.0; + self.0 -= 1; + return Some(ret); + } + None + } + } + impl FusedIterator for TestFusedIter {} + + let mut it = TestFusedIter(15).step_by(5); + assert_eq!(it.next(), Some(15)); + assert_eq!(it.next(), Some(10)); + assert_eq!(it.next(), None); +}