From a66b7810c34987d61131fb18bafd6e815252d22c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 11 Apr 2025 12:23:00 -0700 Subject: [PATCH] `impl Default for RepeatN` This creates an empty iterator, like `repeat_n(value, 0)` but without needing any such value at hand. There's precedent in many other iterators that the `Default` is empty, like `slice::Iter`. I found myself wanting this for rayon's `RepeatN` as it lowers to a sequential iterator [here][1]. Since rayon is also optimizing to avoid extra clones, it may end up with parallel splits that have count 0 and no item value. Calling `std::iter::repeat_n(x, 0)` just drops that value, but there's no way to construct the same result without a value yet. This would be straightforward with an empty `Default`. [1]: https://github.com/rayon-rs/rayon/blob/ae07384e3e0b238cea89f0c14891f351c65a5cee/src/iter/repeat.rs#L201-L202 --- library/core/src/iter/sources/repeat_n.rs | 9 +++++++++ library/coretests/tests/iter/sources.rs | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs index c29ab24a08357..4cbaf41852142 100644 --- a/library/core/src/iter/sources/repeat_n.rs +++ b/library/core/src/iter/sources/repeat_n.rs @@ -102,6 +102,15 @@ impl fmt::Debug for RepeatN { } } +/// Creates an empty iterator, like [`repeat_n(value, 0)`][`repeat_n`] +/// but without needing any such value at hand. +#[stable(feature = "iter_repeat_n_default", since = "CURRENT_RUSTC_VERSION")] +impl Default for RepeatN { + fn default() -> Self { + RepeatN { inner: None } + } +} + #[stable(feature = "iter_repeat_n", since = "1.82.0")] impl Iterator for RepeatN { type Item = A; diff --git a/library/coretests/tests/iter/sources.rs b/library/coretests/tests/iter/sources.rs index 420f3088e6ee4..c1df278b54064 100644 --- a/library/coretests/tests/iter/sources.rs +++ b/library/coretests/tests/iter/sources.rs @@ -192,3 +192,19 @@ fn test_repeat_n_soundness() { let _z = y; assert_eq!(0, *x); } + +#[test] +fn test_repeat_n_default() { + #[derive(Clone)] + pub struct PanicOnDrop; + + impl Drop for PanicOnDrop { + fn drop(&mut self) { + unreachable!() + } + } + + // The default is an empty iterator, so there's never any item to drop. + let iter = RepeatN::::default(); + assert_eq!(iter.count(), 0); +}