Skip to content

Conversation

414owen
Copy link

@414owen 414owen commented Sep 17, 2025

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 #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.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 17, 2025
@rustbot
Copy link
Collaborator

rustbot commented Sep 17, 2025

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

@414owen 414owen force-pushed the os/infinite-iterator branch from 58acbaf to 722ad22 Compare September 17, 2025 08:03
@rust-log-analyzer

This comment has been minimized.

This enables more ExactSizeIterator instances, specifically, those
for `Take`, where the sub-iterator is infinite, and `Zip` where the
one sub-iterator is infinite, and the other is exact sized.

Previously, in rust-lang#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,

```rust
[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.
@414owen 414owen force-pushed the os/infinite-iterator branch from 722ad22 to 13a0203 Compare September 17, 2025 09:44
Copy link
Member

@fmease fmease left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, please don't use negative bounds! They are for internal trait solver tests only!

View changes since this review

@rust-log-analyzer
Copy link
Collaborator

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`.

@414owen
Copy link
Author

414owen commented Sep 17, 2025

@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.

@cuviper
Copy link
Member

cuviper commented Sep 17, 2025

This definitely needs an ACP, and should not be instantly stable.
(regardless of whether this is feasible at all, given the negative-impl concern.)

@cuviper cuviper added needs-acp This change is blocked on the author creating an ACP. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Sep 17, 2025
@fmease
Copy link
Member

fmease commented Sep 17, 2025

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.

@compiler-errors
Copy link
Member

Yeah negative bounds are definitely not stable enough to use even if we are hiding their use behind public facing traits or something.

@cuviper
Copy link
Member

cuviper commented Sep 17, 2025

Ack -- sorry for blurring the line between impls and bounds.

@the8472
Copy link
Member

the8472 commented Sep 17, 2025

A previous attempt: #90093

@tgross35
Copy link
Contributor

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

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 17, 2025
@rustbot
Copy link
Collaborator

rustbot commented Sep 17, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-acp This change is blocked on the author creating an ACP. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants