From 05c7330ca03650bbcb6a55f5fa490b3bb03c1940 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 30 Jul 2022 01:48:16 +0200 Subject: [PATCH 1/4] Implement Default for some alloc/core iterators This way one can `mem::take()` them out of structs or #[derive(Default)] on structs containing them. These changes will be insta-stable. --- .../alloc/src/collections/binary_heap/mod.rs | 7 +++ library/alloc/src/collections/btree/map.rs | 56 +++++++++++++++++++ .../alloc/src/collections/btree/map/tests.rs | 16 ++++++ .../alloc/src/collections/btree/navigate.rs | 12 ++++ library/alloc/src/collections/btree/set.rs | 22 ++++++++ library/alloc/src/collections/linked_list.rs | 21 +++++++ .../src/collections/linked_list/tests.rs | 6 ++ library/alloc/src/vec/into_iter.rs | 7 +++ library/alloc/tests/vec.rs | 10 +++- library/core/src/iter/adapters/chain.rs | 11 ++++ library/core/src/iter/adapters/cloned.rs | 11 ++++ library/core/src/iter/adapters/copied.rs | 11 ++++ library/core/src/iter/adapters/enumerate.rs | 10 ++++ library/core/src/iter/adapters/flatten.rs | 11 ++++ library/core/src/iter/adapters/fuse.rs | 7 +++ library/core/src/iter/adapters/rev.rs | 10 ++++ library/core/src/slice/iter/macros.rs | 7 +++ library/core/tests/slice.rs | 10 +++- 18 files changed, 243 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index f1d0a305d999f..b0ec70ad565f8 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1468,6 +1468,13 @@ impl ExactSizeIterator for IntoIter { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + IntoIter { iter: Default::default() } + } +} + // In addition to the SAFETY invariants of the following three unsafe traits // also refer to the vec::in_place_collect module documentation to get an overview #[unstable(issue = "none", feature = "inplace_iteration")] diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 386cd1a1657e2..c1e8a84969ae0 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -362,6 +362,13 @@ impl fmt::Debug for Iter<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, K: 'a, V: 'a> Default for Iter<'a, K, V> { + fn default() -> Self { + Iter { range: Default::default(), length: 0 } + } +} + /// A mutable iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`iter_mut`] method on [`BTreeMap`]. See its @@ -386,6 +393,13 @@ impl fmt::Debug for IterMut<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> { + fn default() -> Self { + IterMut { range: Default::default(), length: 0, _marker: PhantomData {} } + } +} + /// An owning iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`into_iter`] method on [`BTreeMap`] @@ -421,6 +435,13 @@ impl Debug for IntoIter { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + IntoIter { range: Default::default(), length: 0, alloc: Global } + } +} + /// An iterator over the keys of a `BTreeMap`. /// /// This `struct` is created by the [`keys`] method on [`BTreeMap`]. See its @@ -1768,6 +1789,13 @@ impl Clone for Keys<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Keys<'_, K, V> { + fn default() -> Self { + Keys { inner: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; @@ -1809,6 +1837,13 @@ impl Clone for Values<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Values<'_, K, V> { + fn default() -> Self { + Values { inner: Default::default() } + } +} + /// An iterator produced by calling `drain_filter` on BTreeMap. #[unstable(feature = "btree_drain_filter", issue = "70530")] pub struct DrainFilter< @@ -1945,6 +1980,13 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Range<'_, K, V> { + fn default() -> Self { + Range { inner: Default::default() } + } +} + #[stable(feature = "map_values_mut", since = "1.10.0")] impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { type Item = &'a mut V; @@ -2021,6 +2063,13 @@ impl ExactSizeIterator for IntoKeys { #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl FusedIterator for IntoKeys {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoKeys { + fn default() -> Self { + IntoKeys { inner: Default::default() } + } +} + #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl Iterator for IntoValues { type Item = V; @@ -2055,6 +2104,13 @@ impl ExactSizeIterator for IntoValues { #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl FusedIterator for IntoValues {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoValues { + fn default() -> Self { + IntoValues { inner: Default::default() } + } +} + #[stable(feature = "btree_range", since = "1.17.0")] impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a V)> { diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 76c2f27b46634..4d011195936c6 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -563,6 +563,22 @@ fn test_iter_min_max() { a.check(); } +#[test] +fn test_iters_default() { + let iter: Keys<'_, u8, u8> = Keys::default(); + assert_eq!(iter.len(), 0); + let iter: Values<'_, u8, u8> = Values::default(); + assert_eq!(iter.len(), 0); + let iter: Range<'_, u8, u8> = Range::default(); + assert_eq!(iter.count(), 0); + let iter: IntoIter = IntoIter::default(); + assert_eq!(iter.len(), 0); + let iter: IntoKeys = IntoKeys::default(); + assert_eq!(iter.len(), 0); + let iter: IntoValues = IntoValues::default(); + assert_eq!(iter.len(), 0); +} + fn range_keys(map: &BTreeMap, range: impl RangeBounds) -> Vec { Vec::from_iter(map.range(range).map(|(&k, &v)| { assert_eq!(k, v); diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index b890717e50b25..a85a3162451bf 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -19,6 +19,12 @@ impl<'a, K: 'a, V: 'a> Clone for LeafRange, K, V> { } } +impl Default for LeafRange { + fn default() -> Self { + LeafRange { front: None, back: None } + } +} + impl LeafRange { pub fn none() -> Self { LeafRange { front: None, back: None } @@ -124,6 +130,12 @@ pub struct LazyLeafRange { back: Option>, } +impl Default for LazyLeafRange { + fn default() -> Self { + LazyLeafRange { front: None, back: None } + } +} + impl<'a, K: 'a, V: 'a> Clone for LazyLeafRange, K, V> { fn clone(&self) -> Self { LazyLeafRange { front: self.front.clone(), back: self.back.clone() } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 4ddb211925202..897499db42981 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1544,6 +1544,14 @@ impl Iterator for IntoIter { self.iter.size_hint() } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Iter<'_, T> { + fn default() -> Self { + Iter { iter: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { @@ -1560,6 +1568,13 @@ impl ExactSizeIterator for IntoIter { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + IntoIter { iter: Default::default() } + } +} + #[stable(feature = "btree_range", since = "1.17.0")] impl Clone for Range<'_, T> { fn clone(&self) -> Self { @@ -1598,6 +1613,13 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Range<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Range<'_, T> { + fn default() -> Self { + Range { iter: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Difference<'_, T, A> { fn clone(&self) -> Self { diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index f2f5dffc25d3a..dae7fc48b1f98 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1075,6 +1075,13 @@ impl ExactSizeIterator for Iter<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Iter<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Iter<'_, T> { + fn default() -> Self { + Iter { head: None, tail: None, len: 0, marker: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; @@ -1129,6 +1136,13 @@ impl ExactSizeIterator for IterMut<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IterMut<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IterMut<'_, T> { + fn default() -> Self { + IterMut { head: None, tail: None, len: 0, marker: Default::default() } + } +} + /// A cursor over a `LinkedList`. /// /// A `Cursor` is like an iterator, except that it can freely seek back-and-forth. @@ -1808,6 +1822,13 @@ impl ExactSizeIterator for IntoIter {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + LinkedList::new().into_iter() + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for LinkedList { fn from_iter>(iter: I) -> Self { diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 04594d55b6abf..075c68f724137 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -172,6 +172,12 @@ fn test_iterator() { assert_eq!(it.next(), None); } +#[test] +fn test_default() { + let iter: IntoIter = Default::default(); + assert_eq!(iter.len(), 0); +} + #[test] fn test_iterator_clone() { let mut n = LinkedList::new(); diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 37966007eb7e4..2be484c3dd4d0 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -347,6 +347,13 @@ impl FusedIterator for IntoIter {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + super::Vec::new().into_iter() + } +} + #[doc(hidden)] #[unstable(issue = "none", feature = "std_internals")] #[rustc_unsafe_specialization_marker] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 2f07c2911a502..782b150681c0a 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,5 +1,6 @@ use core::alloc::{Allocator, Layout}; -use core::iter::IntoIterator; +use core::assert_eq; +use core::iter::{ExactSizeIterator, IntoIterator}; use core::ptr::NonNull; use std::alloc::System; use std::assert_matches::assert_matches; @@ -1035,6 +1036,13 @@ fn test_into_iter_clone() { assert_eq!(it.next(), None); } +#[test] +fn test_into_iter_default() { + let iter: IntoIter = Default::default(); + assert_eq!(iter.len(), 0); + assert_eq!(iter.as_slice(), &[]); +} + #[test] fn test_into_iter_leak() { static mut DROPS: i32 = 0; diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 60eb3a6da3a4b..21fc3bc6f6f01 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -282,6 +282,17 @@ where { } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Chain +where + A: Iterator + Default, + B: Iterator + Default, +{ + fn default() -> Self { + Chain::new(Default::default(), Default::default()) + } +} + #[inline] fn and_then_or_clear(opt: &mut Option, f: impl FnOnce(&mut T) -> Option) -> Option { let x = f(opt.as_mut()?); diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index 914ff86c1a959..d22a6e721f583 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -153,3 +153,14 @@ where item.clone() } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, I, T: 'a> Default for Cloned +where + I: Default + Iterator, + T: Clone, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 62d3afb81603d..d5e579834eee8 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -240,3 +240,14 @@ where } } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, I, T: 'a> Default for Copied +where + I: Default + Iterator, + T: Copy, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 14a126951115c..0b44139a83b7a 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -264,3 +264,13 @@ where #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl InPlaceIterable for Enumerate {} + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Enumerate +where + I: Iterator + Default, +{ + fn default() -> Self { + Enumerate::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index b040a0ea9011b..c0a347a7c1d97 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -302,6 +302,17 @@ where { } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Flatten +where + I: Iterator + Default, + ::Item: IntoIterator, +{ + fn default() -> Self { + Flatten::new(Default::default()) + } +} + /// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// this type. #[derive(Clone, Debug)] diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index c931445420342..87275fa3951e4 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -181,6 +181,13 @@ where } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Fuse { + fn default() -> Self { + Fuse { iter: Default::default() } + } +} + #[unstable(feature = "trusted_len", issue = "37572")] // SAFETY: `TrustedLen` requires that an accurate length is reported via `size_hint()`. As `Fuse` // is just forwarding this to the wrapped iterator `I` this property is preserved and it is safe to diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 139fb7bbdd996..4ad75ec0ea298 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -135,3 +135,13 @@ impl FusedIterator for Rev where I: FusedIterator + DoubleEndedIterator {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Rev where I: TrustedLen + DoubleEndedIterator {} + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Rev +where + I: Default + Iterator, +{ + fn default() -> Self { + Rev::new(Default::default()) + } +} diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 89b92a7d5975f..57754182c4e8a 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -393,6 +393,13 @@ macro_rules! iterator { } } } + + #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] + impl Default for $name<'_, T> { + fn default() -> Self { + (& $( $mut_ )? []).into_iter() + } + } } } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 39559cdbb5ea9..294de77a6b07a 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1,8 +1,10 @@ use core::cell::Cell; use core::cmp::Ordering; +use core::iter::ExactSizeIterator; use core::mem::MaybeUninit; use core::result::Result::{Err, Ok}; -use core::slice; +use core::slice::Iter; +use core::{assert_eq, slice}; #[test] fn test_position() { @@ -224,6 +226,12 @@ fn test_iterator_count() { assert_eq!(iter2.count(), 3); } +#[test] +fn test_iterator_default() { + let iter: Iter<'_, u8> = Iter::default(); + assert_eq!(iter.len(), 0); +} + #[test] fn test_chunks_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; From 2b32b315f91536b32ac60ea0d3a93a1feb1d9215 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Thu, 4 Aug 2022 21:31:37 +0200 Subject: [PATCH 2/4] rewrite iterator `Default` tests as doctests --- .../alloc/src/collections/binary_heap/mod.rs | 7 +++ library/alloc/src/collections/btree/map.rs | 56 +++++++++++++++++++ .../alloc/src/collections/btree/map/tests.rs | 16 ------ library/alloc/src/collections/btree/set.rs | 21 +++++++ library/alloc/src/collections/linked_list.rs | 14 +++++ .../src/collections/linked_list/tests.rs | 6 -- library/alloc/src/vec/into_iter.rs | 8 +++ library/alloc/tests/vec.rs | 10 +--- library/core/src/iter/adapters/chain.rs | 15 +++++ library/core/src/iter/adapters/cloned.rs | 7 +++ library/core/src/iter/adapters/copied.rs | 7 +++ library/core/src/iter/adapters/enumerate.rs | 7 +++ library/core/src/iter/adapters/flatten.rs | 8 +++ library/core/src/iter/adapters/fuse.rs | 8 +++ library/core/src/iter/adapters/rev.rs | 7 +++ library/core/src/slice/iter/macros.rs | 7 +++ library/core/tests/slice.rs | 10 +--- 17 files changed, 174 insertions(+), 40 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index b0ec70ad565f8..d0a87e3fb9fd5 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1470,6 +1470,13 @@ impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `binary_heap::IntoIter`. + /// + /// ``` + /// # use std::collections::binary_heap; + /// let iter: binary_heap::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoIter { iter: Default::default() } } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index c1e8a84969ae0..8c8a459fec95c 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -364,6 +364,13 @@ impl fmt::Debug for Iter<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl<'a, K: 'a, V: 'a> Default for Iter<'a, K, V> { + /// Creates an empty `btree_map::Iter`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Iter<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Iter { range: Default::default(), length: 0 } } @@ -395,6 +402,13 @@ impl fmt::Debug for IterMut<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> { + /// Creates an empty `btree_map::IterMut`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IterMut<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IterMut { range: Default::default(), length: 0, _marker: PhantomData {} } } @@ -437,6 +451,13 @@ impl Debug for IntoIter { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `btree_map::IntoIter`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoIter { range: Default::default(), length: 0, alloc: Global } } @@ -1791,6 +1812,13 @@ impl Clone for Keys<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Keys<'_, K, V> { + /// Creates an empty `btree_map::Keys`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Keys<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Keys { inner: Default::default() } } @@ -1839,6 +1867,13 @@ impl Clone for Values<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Values<'_, K, V> { + /// Creates an empty `btree_map::Values`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Values<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Values { inner: Default::default() } } @@ -1982,6 +2017,13 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Range<'_, K, V> { + /// Creates an empty `btree_map::Range`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Range<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.count(), 0); + /// ``` fn default() -> Self { Range { inner: Default::default() } } @@ -2065,6 +2107,13 @@ impl FusedIterator for IntoKeys {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoKeys { + /// Creates an empty `btree_map::IntoKeys`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IntoKeys = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoKeys { inner: Default::default() } } @@ -2106,6 +2155,13 @@ impl FusedIterator for IntoValues {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoValues { + /// Creates an empty `btree_map::IntoValues`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IntoValues = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoValues { inner: Default::default() } } diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 4d011195936c6..76c2f27b46634 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -563,22 +563,6 @@ fn test_iter_min_max() { a.check(); } -#[test] -fn test_iters_default() { - let iter: Keys<'_, u8, u8> = Keys::default(); - assert_eq!(iter.len(), 0); - let iter: Values<'_, u8, u8> = Values::default(); - assert_eq!(iter.len(), 0); - let iter: Range<'_, u8, u8> = Range::default(); - assert_eq!(iter.count(), 0); - let iter: IntoIter = IntoIter::default(); - assert_eq!(iter.len(), 0); - let iter: IntoKeys = IntoKeys::default(); - assert_eq!(iter.len(), 0); - let iter: IntoValues = IntoValues::default(); - assert_eq!(iter.len(), 0); -} - fn range_keys(map: &BTreeMap, range: impl RangeBounds) -> Vec { Vec::from_iter(map.range(range).map(|(&k, &v)| { assert_eq!(k, v); diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 897499db42981..5992b814bba73 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1547,6 +1547,13 @@ impl Iterator for IntoIter { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Iter<'_, T> { + /// Creates an empty `btree_set::Iter`. + /// + /// ``` + /// # use std::collections::btree_set; + /// let iter: btree_set::Iter<'_, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Iter { iter: Default::default() } } @@ -1570,6 +1577,13 @@ impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `btree_set::IntoIter`. + /// + /// ``` + /// # use std::collections::btree_set; + /// let iter: btree_set::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoIter { iter: Default::default() } } @@ -1615,6 +1629,13 @@ impl FusedIterator for Range<'_, T> {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Range<'_, T> { + /// Creates an empty `btree_set::Range`. + /// + /// ``` + /// # use std::collections::btree_set; + /// let iter: btree_set::Range<'_, u8> = Default::default(); + /// assert_eq!(iter.count(), 0); + /// ``` fn default() -> Self { Range { iter: Default::default() } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index dae7fc48b1f98..080a4a14eda6e 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1077,6 +1077,13 @@ impl FusedIterator for Iter<'_, T> {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Iter<'_, T> { + /// Creates an empty `linked_list::Iter`. + /// + /// ``` + /// # use std::collections::linked_list; + /// let iter: linked_list::Iter<'_, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Iter { head: None, tail: None, len: 0, marker: Default::default() } } @@ -1824,6 +1831,13 @@ impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `linked_list::IntoIter`. + /// + /// ``` + /// # use std::collections::linked_list; + /// let iter: linked_list::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { LinkedList::new().into_iter() } diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 075c68f724137..04594d55b6abf 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -172,12 +172,6 @@ fn test_iterator() { assert_eq!(it.next(), None); } -#[test] -fn test_default() { - let iter: IntoIter = Default::default(); - assert_eq!(iter.len(), 0); -} - #[test] fn test_iterator_clone() { let mut n = LinkedList::new(); diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 2be484c3dd4d0..8fed4a584a377 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -349,6 +349,14 @@ unsafe impl TrustedLen for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `vec::IntoIter`. + /// + /// ``` + /// # use std::vec; + /// let iter: vec::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// assert_eq!(iter.as_slice(), &[]); + /// ``` fn default() -> Self { super::Vec::new().into_iter() } diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 782b150681c0a..2f07c2911a502 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,6 +1,5 @@ use core::alloc::{Allocator, Layout}; -use core::assert_eq; -use core::iter::{ExactSizeIterator, IntoIterator}; +use core::iter::IntoIterator; use core::ptr::NonNull; use std::alloc::System; use std::assert_matches::assert_matches; @@ -1036,13 +1035,6 @@ fn test_into_iter_clone() { assert_eq!(it.next(), None); } -#[test] -fn test_into_iter_default() { - let iter: IntoIter = Default::default(); - assert_eq!(iter.len(), 0); - assert_eq!(iter.as_slice(), &[]); -} - #[test] fn test_into_iter_leak() { static mut DROPS: i32 = 0; diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 21fc3bc6f6f01..0f5e3718408ce 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -288,6 +288,21 @@ where A: Iterator + Default, B: Iterator + Default, { + /// Creates a `Chain` from the default values for `A` and `B`. + /// + /// ``` + /// # use core::iter::Chain; + /// # use core::slice; + /// # use std::collections::{btree_set, BTreeSet}; + /// # use std::mem; + /// struct Foo<'a>(Chain, btree_set::Iter<'a, u8>>); + /// + /// let set = BTreeSet::::new(); + /// let slice: &[u8] = &[]; + /// let mut foo = Foo(slice.iter().chain(set.iter())); + /// + /// // take requires `Default` + /// let _: Chain<_, _> = mem::take(&mut foo.0); fn default() -> Self { Chain::new(Default::default(), Default::default()) } diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index d22a6e721f583..b9e2700860c06 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -160,6 +160,13 @@ where I: Default + Iterator, T: Clone, { + /// Creates a `Cloned` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use core::iter::Cloned; + /// let iter: Cloned> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Self::new(Default::default()) } diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index d5e579834eee8..0aa466e37a217 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -247,6 +247,13 @@ where I: Default + Iterator, T: Copy, { + /// Creates a `Copied` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use core::iter::Copied; + /// let iter: Copied> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Self::new(Default::default()) } diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 0b44139a83b7a..5b0025cb9849a 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -270,6 +270,13 @@ impl Default for Enumerate where I: Iterator + Default, { + /// Creates an `Enumerate` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use std::iter::Enumerate; + /// let iter: Enumerate> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Enumerate::new(Default::default()) } diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index c0a347a7c1d97..cb68c807bf5fc 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -308,6 +308,14 @@ where I: Iterator + Default, ::Item: IntoIterator, { + /// Creates a `Flatten` iterator from the default value of `I`. + /// + /// ``` + /// # use core::slice; + /// # use std::iter::Flatten; + /// let iter: Flatten> = Default::default(); + /// assert_eq!(iter.count(), 0); + /// ``` fn default() -> Self { Flatten::new(Default::default()) } diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index 87275fa3951e4..de91c188eeb2a 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -183,6 +183,14 @@ where #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Fuse { + /// Creates a `Fuse` iterator from the default value of `I`. + /// + /// ``` + /// # use core::slice; + /// # use std::iter::Fuse; + /// let iter: Fuse> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Fuse { iter: Default::default() } } diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 4ad75ec0ea298..0b132e138131a 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -141,6 +141,13 @@ impl Default for Rev where I: Default + Iterator, { + /// Creates a `Rev` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use core::iter::Rev; + /// let iter: Rev> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Rev::new(Default::default()) } diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 57754182c4e8a..a800da546b450 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -396,6 +396,13 @@ macro_rules! iterator { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for $name<'_, T> { + /// Creates an empty slice iterator. + /// + /// ``` + #[doc = concat!("# use core::slice::", stringify!($name), ";")] + #[doc = concat!("let iter: ", stringify!($name<'_, u8>), " = Default::default();")] + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { (& $( $mut_ )? []).into_iter() } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 294de77a6b07a..39559cdbb5ea9 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1,10 +1,8 @@ use core::cell::Cell; use core::cmp::Ordering; -use core::iter::ExactSizeIterator; use core::mem::MaybeUninit; use core::result::Result::{Err, Ok}; -use core::slice::Iter; -use core::{assert_eq, slice}; +use core::slice; #[test] fn test_position() { @@ -226,12 +224,6 @@ fn test_iterator_count() { assert_eq!(iter2.count(), 3); } -#[test] -fn test_iterator_default() { - let iter: Iter<'_, u8> = Iter::default(); - assert_eq!(iter.len(), 0); -} - #[test] fn test_chunks_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; From a4bdfe24c5f83cbb03febdb9ab5fd22414eac05f Mon Sep 17 00:00:00 2001 From: The 8472 Date: Tue, 25 Oct 2022 22:55:04 +0200 Subject: [PATCH 3/4] Support allocators in various Default for IntoIter impls Global implements Default so we can use that as bound for all allocators --- library/alloc/src/collections/btree/map.rs | 17 +++++++++++++---- library/alloc/src/collections/btree/set.rs | 5 ++++- library/alloc/src/vec/into_iter.rs | 7 +++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 8c8a459fec95c..61db46314b780 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -450,7 +450,10 @@ impl Debug for IntoIter { } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoIter { +impl Default for IntoIter +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_map::IntoIter`. /// /// ``` @@ -459,7 +462,7 @@ impl Default for IntoIter { /// assert_eq!(iter.len(), 0); /// ``` fn default() -> Self { - IntoIter { range: Default::default(), length: 0, alloc: Global } + IntoIter { range: Default::default(), length: 0, alloc: Default::default() } } } @@ -2106,7 +2109,10 @@ impl ExactSizeIterator for IntoKeys { impl FusedIterator for IntoKeys {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoKeys { +impl Default for IntoKeys +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_map::IntoKeys`. /// /// ``` @@ -2154,7 +2160,10 @@ impl ExactSizeIterator for IntoValues { impl FusedIterator for IntoValues {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoValues { +impl Default for IntoValues +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_map::IntoValues`. /// /// ``` diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 5992b814bba73..c2233f86667fb 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1576,7 +1576,10 @@ impl ExactSizeIterator for IntoIter { impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoIter { +impl Default for IntoIter +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_set::IntoIter`. /// /// ``` diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 8fed4a584a377..f6525eb900386 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -348,7 +348,10 @@ impl FusedIterator for IntoIter {} unsafe impl TrustedLen for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoIter { +impl Default for IntoIter +where + A: Allocator + Default, +{ /// Creates an empty `vec::IntoIter`. /// /// ``` @@ -358,7 +361,7 @@ impl Default for IntoIter { /// assert_eq!(iter.as_slice(), &[]); /// ``` fn default() -> Self { - super::Vec::new().into_iter() + super::Vec::new_in(Default::default()).into_iter() } } From e44836faf6ff114805062f723b349d6e10bf86b6 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Tue, 28 Feb 2023 21:16:33 +0100 Subject: [PATCH 4/4] relax bounds on iterator adapter Default impls --- library/core/src/iter/adapters/chain.rs | 6 +----- library/core/src/iter/adapters/cloned.rs | 6 +----- library/core/src/iter/adapters/copied.rs | 6 +----- library/core/src/iter/adapters/enumerate.rs | 5 +---- library/core/src/iter/adapters/flatten.rs | 3 +-- library/core/src/iter/adapters/rev.rs | 5 +---- 6 files changed, 6 insertions(+), 25 deletions(-) diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 0f5e3718408ce..d4b2640e81dc9 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -283,11 +283,7 @@ where } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for Chain -where - A: Iterator + Default, - B: Iterator + Default, -{ +impl Default for Chain { /// Creates a `Chain` from the default values for `A` and `B`. /// /// ``` diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index b9e2700860c06..bb7e1660c6eb2 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -155,11 +155,7 @@ where } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl<'a, I, T: 'a> Default for Cloned -where - I: Default + Iterator, - T: Clone, -{ +impl Default for Cloned { /// Creates a `Cloned` iterator from the default value of `I` /// ``` /// # use core::slice; diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 0aa466e37a217..a076ab925e366 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -242,11 +242,7 @@ where } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl<'a, I, T: 'a> Default for Copied -where - I: Default + Iterator, - T: Copy, -{ +impl Default for Copied { /// Creates a `Copied` iterator from the default value of `I` /// ``` /// # use core::slice; diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 5b0025cb9849a..8c32a35a12f86 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -266,10 +266,7 @@ where unsafe impl InPlaceIterable for Enumerate {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for Enumerate -where - I: Iterator + Default, -{ +impl Default for Enumerate { /// Creates an `Enumerate` iterator from the default value of `I` /// ``` /// # use core::slice; diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index cb68c807bf5fc..e4020c45f71bc 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -305,8 +305,7 @@ where #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Flatten where - I: Iterator + Default, - ::Item: IntoIterator, + I: Default + Iterator, { /// Creates a `Flatten` iterator from the default value of `I`. /// diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 0b132e138131a..8ae6d96fde4cc 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -137,10 +137,7 @@ impl FusedIterator for Rev where I: FusedIterator + DoubleEndedIterator {} unsafe impl TrustedLen for Rev where I: TrustedLen + DoubleEndedIterator {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for Rev -where - I: Default + Iterator, -{ +impl Default for Rev { /// Creates a `Rev` iterator from the default value of `I` /// ``` /// # use core::slice;