From bcefe67657984328cc3ce524b70bd3380bf2949b Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 20 Oct 2021 08:02:09 +0000 Subject: [PATCH] Endless Iterators --- library/core/src/iter/adapters/chain.rs | 7 ++++ library/core/src/iter/adapters/cloned.rs | 9 +++++ library/core/src/iter/adapters/copied.rs | 9 +++++ library/core/src/iter/adapters/cycle.rs | 11 +++++- library/core/src/iter/adapters/filter.rs | 4 ++ library/core/src/iter/adapters/filter_map.rs | 8 +++- library/core/src/iter/adapters/flatten.rs | 37 +++++++++++++++++++ library/core/src/iter/adapters/fuse.rs | 4 ++ library/core/src/iter/adapters/inspect.rs | 4 ++ library/core/src/iter/adapters/intersperse.rs | 8 ++++ library/core/src/iter/adapters/map.rs | 9 +++++ library/core/src/iter/adapters/peekable.rs | 4 ++ library/core/src/iter/adapters/rev.rs | 4 ++ library/core/src/iter/adapters/skip.rs | 5 ++- library/core/src/iter/adapters/skip_while.rs | 7 ++++ library/core/src/iter/adapters/step_by.rs | 9 ++++- library/core/src/iter/adapters/take.rs | 6 ++- library/core/src/iter/adapters/zip.rs | 7 ++++ library/core/src/iter/sources/repeat.rs | 5 ++- library/core/src/iter/traits/marker.rs | 23 ++++++++++++ library/core/src/iter/traits/mod.rs | 4 ++ library/core/src/lib.rs | 1 + 22 files changed, 178 insertions(+), 7 deletions(-) diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 53e48500e3b4d..a0c6a678caf1f 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -1,3 +1,4 @@ +use crate::iter::traits::EndlessIterator; use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen}; use crate::ops::Try; @@ -324,3 +325,9 @@ where B: TrustedLen, { } + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Chain where B: Iterator {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Chain where A: Iterator {} diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index 71a5a4ea831ff..87ad38cf75d63 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -1,6 +1,7 @@ use crate::iter::adapters::{ zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce, }; +use crate::iter::traits::EndlessIterator; use crate::iter::{FusedIterator, TrustedLen}; use crate::ops::Try; @@ -141,3 +142,11 @@ where T: Clone, { } + +#[unstable(issue = "none", feature = "endless")] +unsafe impl<'a, I, T: 'a> EndlessIterator for Cloned +where + I: EndlessIterator, + T: Clone, +{ +} diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index e5f2886dcafad..64a0b558f8593 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -1,6 +1,7 @@ use crate::iter::adapters::{ zip::try_get_unchecked, TrustedRandomAccess, TrustedRandomAccessNoCoerce, }; +use crate::iter::traits::EndlessIterator; use crate::iter::{FusedIterator, TrustedLen}; use crate::ops::Try; @@ -167,3 +168,11 @@ where T: Copy, { } + +#[unstable(issue = "none", feature = "endless")] +unsafe impl<'a, I, T: 'a> EndlessIterator for Copied +where + I: EndlessIterator, + T: Copy, +{ +} diff --git a/library/core/src/iter/adapters/cycle.rs b/library/core/src/iter/adapters/cycle.rs index 02b5939072ef0..53ddb6e6e56b6 100644 --- a/library/core/src/iter/adapters/cycle.rs +++ b/library/core/src/iter/adapters/cycle.rs @@ -1,4 +1,10 @@ -use crate::{iter::FusedIterator, ops::Try}; +use crate::{ + iter::{ + traits::{EndlessIterator, EndlessOrExact}, + FusedIterator, + }, + ops::Try, +}; /// An iterator that repeats endlessly. /// @@ -106,3 +112,6 @@ where #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Cycle where I: Clone + Iterator {} + +#[unstable(issue = "none", feature = "none")] +unsafe impl EndlessIterator for Cycle where I: Clone + EndlessOrExact {} diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index a0afaa326ad63..01511479bb472 100644 --- a/library/core/src/iter/adapters/filter.rs +++ b/library/core/src/iter/adapters/filter.rs @@ -1,4 +1,5 @@ use crate::fmt; +use crate::iter::traits::EndlessIterator; use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable}; use crate::ops::Try; @@ -150,3 +151,6 @@ where #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl InPlaceIterable for Filter where P: FnMut(&I::Item) -> bool {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Filter where P: FnMut(&I::Item) -> bool {} diff --git a/library/core/src/iter/adapters/filter_map.rs b/library/core/src/iter/adapters/filter_map.rs index e0d665c9e12ba..44f2504710978 100644 --- a/library/core/src/iter/adapters/filter_map.rs +++ b/library/core/src/iter/adapters/filter_map.rs @@ -1,5 +1,5 @@ use crate::fmt; -use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable}; +use crate::iter::{adapters::SourceIter, traits::EndlessIterator, FusedIterator, InPlaceIterable}; use crate::ops::{ControlFlow, Try}; /// An iterator that uses `f` to both filter and map elements from `iter`. @@ -147,3 +147,9 @@ unsafe impl InPlaceIterable for FilterMap where F: FnMut(I::Item) -> Option { } + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for FilterMap where + F: FnMut(I::Item) -> Option +{ +} diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 351fd569d8acf..13d518fce51b0 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -1,4 +1,5 @@ use crate::fmt; +use crate::iter::traits::{EndlessIterator, EndlessOrExact}; use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen}; use crate::ops::Try; @@ -138,6 +139,26 @@ where { } +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for FlatMap +where + I: EndlessIterator, + U: IntoIterator, + U::IntoIter: EndlessOrExact, + F: FnMut(I::Item) -> U, +{ +} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for FlatMap +where + I: EndlessOrExact, + U: IntoIterator, + U::IntoIter: EndlessIterator, + F: FnMut(I::Item) -> U, +{ +} + /// An iterator that flattens one level of nesting in an iterator of things /// that can be turned into iterators. /// @@ -262,6 +283,22 @@ where { } +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Flatten +where + I: EndlessIterator, + I::Item: EndlessOrExact, +{ +} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Flatten +where + I: EndlessOrExact, + I::Item: EndlessIterator, +{ +} + /// 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 fbf752c6f2024..84691c85d6181 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -1,5 +1,6 @@ use crate::intrinsics; use crate::iter::adapters::zip::try_get_unchecked; +use crate::iter::traits::EndlessIterator; use crate::iter::{ DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce, @@ -233,6 +234,9 @@ where const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT; } +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Fuse {} + /// Fuse specialization trait /// /// We only need to worry about `&mut self` methods, which diff --git a/library/core/src/iter/adapters/inspect.rs b/library/core/src/iter/adapters/inspect.rs index 19839fdfe5bc3..d9595a763dcdb 100644 --- a/library/core/src/iter/adapters/inspect.rs +++ b/library/core/src/iter/adapters/inspect.rs @@ -1,4 +1,5 @@ use crate::fmt; +use crate::iter::traits::EndlessIterator; use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable}; use crate::ops::Try; @@ -164,3 +165,6 @@ where #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl InPlaceIterable for Inspect where F: FnMut(&I::Item) {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Inspect where F: FnMut(&I::Item) {} diff --git a/library/core/src/iter/adapters/intersperse.rs b/library/core/src/iter/adapters/intersperse.rs index d8bbd424cf258..d2b82468a673c 100644 --- a/library/core/src/iter/adapters/intersperse.rs +++ b/library/core/src/iter/adapters/intersperse.rs @@ -1,3 +1,5 @@ +use crate::iter::traits::EndlessIterator; + use super::Peekable; /// An iterator adapter that places a separator between all elements. @@ -57,6 +59,9 @@ where } } +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Intersperse where I::Item: Clone {} + /// An iterator adapter that places a separator between all elements. /// /// This `struct` is created by [`Iterator::intersperse_with`]. See its @@ -185,3 +190,6 @@ where accum }) } + +#[unstable(issue = "none", feature = "endless")] +unsafe impl I::Item> EndlessIterator for IntersperseWith {} diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index 449650a22f435..c2beaa9693cc3 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -2,6 +2,7 @@ use crate::fmt; use crate::iter::adapters::{ zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce, }; +use crate::iter::traits::EndlessIterator; use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen}; use crate::ops::Try; @@ -216,3 +217,11 @@ where #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl InPlaceIterable for Map where F: FnMut(I::Item) -> B {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Map +where + I: EndlessIterator, + F: FnMut(I::Item) -> B, +{ +} diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index 20aca323bab79..0cfb3c8dee90f 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -1,3 +1,4 @@ +use crate::iter::traits::EndlessIterator; use crate::iter::{adapters::SourceIter, FusedIterator, TrustedLen}; use crate::ops::{ControlFlow, Try}; @@ -333,3 +334,6 @@ where unsafe { SourceIter::as_inner(&mut self.iter) } } } + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Peekable {} diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 139fb7bbdd996..bd75c58edf7b6 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -1,3 +1,4 @@ +use crate::iter::traits::EndlessIterator; use crate::iter::{FusedIterator, TrustedLen}; use crate::ops::Try; @@ -135,3 +136,6 @@ impl FusedIterator for Rev where I: FusedIterator + DoubleEndedIterator {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Rev where I: TrustedLen + DoubleEndedIterator {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Rev where I: EndlessIterator + DoubleEndedIterator {} diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs index 565fc224f53ca..1b9aa8df4ac95 100644 --- a/library/core/src/iter/adapters/skip.rs +++ b/library/core/src/iter/adapters/skip.rs @@ -1,5 +1,5 @@ use crate::intrinsics::unlikely; -use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable}; +use crate::iter::{adapters::SourceIter, traits::EndlessIterator, FusedIterator, InPlaceIterable}; use crate::ops::{ControlFlow, Try}; /// An iterator that skips over `n` elements of `iter`. @@ -237,3 +237,6 @@ where #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl InPlaceIterable for Skip {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Skip {} diff --git a/library/core/src/iter/adapters/skip_while.rs b/library/core/src/iter/adapters/skip_while.rs index f29661779c056..7efa683511ac6 100644 --- a/library/core/src/iter/adapters/skip_while.rs +++ b/library/core/src/iter/adapters/skip_while.rs @@ -1,4 +1,5 @@ use crate::fmt; +use crate::iter::traits::EndlessIterator; use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable}; use crate::ops::Try; @@ -123,3 +124,9 @@ unsafe impl InPlaceIterable for SkipWhile where F: FnMut(&I::Item) -> bool { } + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for SkipWhile where + F: FnMut(&I::Item) -> bool +{ +} diff --git a/library/core/src/iter/adapters/step_by.rs b/library/core/src/iter/adapters/step_by.rs index 4252c34a0e0fc..a228809b4b51d 100644 --- a/library/core/src/iter/adapters/step_by.rs +++ b/library/core/src/iter/adapters/step_by.rs @@ -1,4 +1,8 @@ -use crate::{intrinsics, iter::from_fn, ops::Try}; +use crate::{ + intrinsics, + iter::{from_fn, traits::EndlessIterator}, + ops::Try, +}; /// An iterator for stepping iterators by a custom amount. /// @@ -233,3 +237,6 @@ where // StepBy can only make the iterator shorter, so the len will still fit. #[stable(feature = "iterator_step_by", since = "1.28.0")] impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for StepBy {} diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index 81f6c294fac13..9aea9088aa11e 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -1,5 +1,7 @@ use crate::cmp; -use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen}; +use crate::iter::{ + adapters::SourceIter, traits::EndlessOrExact, FusedIterator, InPlaceIterable, TrustedLen, +}; use crate::ops::{ControlFlow, Try}; /// An iterator that only iterates over the first `n` iterations of `iter`. @@ -234,7 +236,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Take where I: ExactSizeIterator {} +impl ExactSizeIterator for Take where I: EndlessOrExact {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Take where I: FusedIterator {} diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index 2b7287a413376..81ed487c73366 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -1,5 +1,6 @@ use crate::cmp; use crate::fmt::{self, Debug}; +use crate::iter::traits::EndlessIterator; use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator}; use crate::iter::{InPlaceIterable, SourceIter, TrustedLen}; @@ -435,6 +436,12 @@ where // (without calling next()) would be needed to properly drop the remainder of the source. unsafe impl InPlaceIterable for Zip where A::Item: Copy {} +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Zip {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Zip {} + #[stable(feature = "rust1", since = "1.0.0")] impl Debug for Zip { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs index 733142ed01103..9163324e8c8d3 100644 --- a/library/core/src/iter/sources/repeat.rs +++ b/library/core/src/iter/sources/repeat.rs @@ -1,4 +1,4 @@ -use crate::iter::{FusedIterator, TrustedLen}; +use crate::iter::{traits::EndlessIterator, FusedIterator, TrustedLen}; /// Creates a new iterator that endlessly repeats a single element. /// @@ -127,3 +127,6 @@ impl FusedIterator for Repeat {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Repeat {} + +#[unstable(issue = "none", feature = "endless")] +unsafe impl EndlessIterator for Repeat {} diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs index 844459d77cd96..c1ced6e6d654f 100644 --- a/library/core/src/iter/traits/marker.rs +++ b/library/core/src/iter/traits/marker.rs @@ -72,3 +72,26 @@ pub unsafe trait InPlaceIterable: Iterator {} #[unstable(feature = "trusted_step", issue = "85731")] #[rustc_specialization_trait] pub unsafe trait TrustedStep: Step {} + +/// An iterator that is either empty or endless. +/// +/// The iterator reports a size hint that is either `0, Some(0)` or `usize::MAX, None`. +/// Since this is used to implement `ExactSizeIterator` for some adapters, iterators that +/// are only empty should not implement this. +/// +/// # Safety +/// +/// The implementation must either be endless or empty. +#[unstable(issue = "none", feature = "endless")] +#[marker] +pub unsafe trait EndlessIterator: Iterator {} + +#[unstable(issue = "none", feature = "endless")] +#[marker] +pub trait EndlessOrExact: Iterator {} + +#[unstable(issue = "none", feature = "endless")] +impl EndlessOrExact for T {} + +#[unstable(issue = "none", feature = "endless")] +impl EndlessOrExact for T {} diff --git a/library/core/src/iter/traits/mod.rs b/library/core/src/iter/traits/mod.rs index ffd745a46b12c..6629d695dc312 100644 --- a/library/core/src/iter/traits/mod.rs +++ b/library/core/src/iter/traits/mod.rs @@ -11,6 +11,10 @@ pub use self::double_ended::DoubleEndedIterator; pub use self::exact_size::ExactSizeIterator; #[stable(feature = "rust1", since = "1.0.0")] pub use self::iterator::Iterator; +#[unstable(issue = "none", feature = "endless")] +pub use self::marker::EndlessIterator; +#[unstable(issue = "none", feature = "endless")] +pub(super) use self::marker::EndlessOrExact; #[unstable(issue = "none", feature = "inplace_iteration")] pub use self::marker::InPlaceIterable; #[unstable(feature = "trusted_step", issue = "85731")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 13b80c05dbb30..a4849da257b1b 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -167,6 +167,7 @@ #![feature(lang_items)] #![feature(link_llvm_intrinsics)] #![feature(llvm_asm)] +#![feature(marker_trait_attr)] #![feature(min_specialization)] #![feature(mixed_integer_ops)] #![cfg_attr(not(bootstrap), feature(must_not_suspend))]