Add InfiniteIterator trait
This enables more ExactSizeIterator instances, specifically, those
for Take, where the sub-iterator is infinite, and Zip where
one sub-iterator is infinite, and the other is exact sized.
Previously, in https://github.com/rust-lang/rust/pull/146642,
I sought to add specific instances for Zip<Repeat<A>, I> and its
symmatrical mirror.
Introducing InfiniteIterator provides much broader support for
ExactSizeIterator.
For example,
[1, 2, 3].into_iter().chain(repeat(1)).take(5)
Will now happily resolve to an instance of ExactSizeIterator.
The downside of this approach is that, to avoid the overlapping instance
with Zip, I had to introduce a negative trait bound, which, IIUC,
isn't available outside of the compiler.
If anyone knows of a better way to handle the overlapping instances, or a way I can expose something which triggers the negative instance, that would be very helpful.
There's also a missing symmetrical instance for Chain. Solutions
are welcome.
r? @tgross35
rustbot has assigned @tgross35. They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.
Use r? to explicitly pick a reviewer
The job aarch64-gnu-llvm-19-1 failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)
---- library/core/src/iter/traits/infinite.rs - iter::traits::infinite::InfiniteIterator (line 14) stdout ----
error[E0405]: cannot find trait `InfiniteIterator` in this scope
--> library/core/src/iter/traits/infinite.rs:15:16
|
4 | impl<A: Clone> InfiniteIterator for Repeat<A> {}
| ^^^^^^^^^^^^^^^^
|
::: /checkout/library/core/src/iter/traits/collect.rs:282:1
|
282 | pub trait IntoIterator {
| ---------------------- similarly named trait `IntoIterator` defined here
|
help: a trait with a similar name exists
|
4 - impl<A: Clone> InfiniteIterator for Repeat<A> {}
4 + impl<A: Clone> IntoIterator for Repeat<A> {}
|
help: consider importing this trait
|
3 + use std::iter::InfiniteIterator;
|
error[E0412]: cannot find type `Repeat` in this scope
--> library/core/src/iter/traits/infinite.rs:15:37
|
4 | impl<A: Clone> InfiniteIterator for Repeat<A> {}
| ^^^^^^ not found in this scope
|
help: consider importing one of these structs
|
3 + use std::io::Repeat;
---
error[E0412]: cannot find type `Zip` in this scope
--> library/core/src/iter/traits/infinite.rs:16:60
|
5 | impl<A: Clone, B: ExactSizeIterator> ExactSizeIterator for Zip<Repeat<A>, B> {}
| ^^^ not found in this scope
|
help: consider importing this struct
|
3 + use std::iter::Zip;
|
error[E0412]: cannot find type `Repeat` in this scope
--> library/core/src/iter/traits/infinite.rs:16:64
|
5 | impl<A: Clone, B: ExactSizeIterator> ExactSizeIterator for Zip<Repeat<A>, B> {}
| ^^^^^^ not found in this scope
|
help: consider importing one of these structs
|
3 + use std::io::Repeat;
---
error[E0412]: cannot find type `Zip` in this scope
--> library/core/src/iter/traits/infinite.rs:17:60
|
6 | impl<A: ExactSizeIterator, B: Clone> ExactSizeIterator for Zip<A, Repeat<B>> {}
| ^^^ not found in this scope
|
help: consider importing this struct
|
3 + use std::iter::Zip;
|
error[E0412]: cannot find type `Repeat` in this scope
--> library/core/src/iter/traits/infinite.rs:17:67
|
6 | impl<A: ExactSizeIterator, B: Clone> ExactSizeIterator for Zip<A, Repeat<B>> {}
| ^^^^^^ not found in this scope
|
help: consider importing one of these structs
|
3 + use std::io::Repeat;
---
---- library/core/src/iter/traits/infinite.rs - iter::traits::infinite::InfiniteIterator (line 5) stdout ----
error[E0425]: cannot find function `repeat` in this scope
--> library/core/src/iter/traits/infinite.rs:6:15
|
4 | [1, 2, 3].zip(repeat(4))
| ^^^^^^ not found in this scope
|
help: consider importing one of these functions
|
3 + use std::array::repeat;
---
3 + use core::array::repeat;
|
= and 1 other candidate
error[E0599]: the method `zip` exists for array `[{integer}; 3]`, but its trait bounds were not satisfied
--> library/core/src/iter/traits/infinite.rs:6:11
|
4 | [1, 2, 3].zip(repeat(4))
| ^^^ method cannot be called on `[{integer}; 3]` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`[{integer}; 3]: Iterator`
which is required by `&mut [{integer}; 3]: Iterator`
`[{integer}]: Iterator`
which is required by `&mut [{integer}]: Iterator`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0425, E0599.
For more information about an error, try `rustc --explain E0425`.
The job pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)
Click to see the possible cause of the failure (guessed by this bot)
---- library/core/src/iter/traits/infinite.rs - iter::traits::infinite::InfiniteIterator (line 5) stdout ----
error[E0425]: cannot find function `repeat` in this scope
--> library/core/src/iter/traits/infinite.rs:6:15
|
4 | [1, 2, 3].zip(repeat(4))
| ^^^^^^ not found in this scope
|
help: consider importing one of these functions
|
3 + use std::array::repeat;
---
3 + use core::array::repeat;
|
= and 1 other candidate
error[E0599]: the method `zip` exists for array `[{integer}; 3]`, but its trait bounds were not satisfied
--> library/core/src/iter/traits/infinite.rs:6:11
|
4 | [1, 2, 3].zip(repeat(4))
| ^^^ method cannot be called on `[{integer}; 3]` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`[{integer}; 3]: Iterator`
which is required by `&mut [{integer}; 3]: Iterator`
`[{integer}]: Iterator`
which is required by `&mut [{integer}]: Iterator`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0425, E0599.
For more information about an error, try `rustc --explain E0425`.
@fmease yeah trust me I didn't want to use them.
I don't suppose there's another way to have the overlapping instances of ExactSizeIterator accepted by the compiler?
I need this kind of thing to be accepted:
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
impl<I> ExactSizeIterator for Take<I> where I: InfiniteIterator {}
I know no type will ever implement InfiniteIterator and ExactSizeIterator, so this overlapping instance is safe, I just need to convince the compiler.
This definitely needs an ACP, and should not be instantly stable. (regardless of whether this is feasible at all, given the negative-impl concern.)
Oh, please don't use negative bounds! They are for internal trait solver tests only!
given the negative-impl concern
I didn't really look at the negative impls (tho adding any negative impls is an incredibly strong SemVer promise and shouldn't be taken lightly), I'm mostly concerned with the use of negative bounds.
These are more than internal; they are so internal that we don't even advertise the name of their lang feature in diagnostics on the nightly channel. Their implementation is not complete (maybe even unsound), they don't have any backing RFC or unofficial proposal. They should not be used inside library/ and I will unfortunately have to hard-block any PR trying to use them in the stdlib.
cc @compiler-errors for a second opinion.
Yeah negative bounds are definitely not stable enough to use even if we are hiding their use behind public facing traits or something.
Ack -- sorry for blurring the line between impls and bounds.
A previous attempt: #90093
As Josh mentioned, please open an ACP with this proposal, it's an issue template at https://github.com/rust-lang/libs-team/issues.
@rustbot author
Reminder, once the PR becomes ready for a review, use @rustbot ready.
New ACP, proposing a different solution, using only stable rust features: https://github.com/rust-lang/libs-team/issues/659
Would appreciate any feedback.
:umbrella: The latest upstream changes (presumably #149495) made this pull request unmergeable. Please resolve the merge conflicts.