Repository: rust
Issue: Unable to call reverse on a Zip Iterator zipping a std::iter::Repeat
Labels: C-enhancement,T-libs-api,A-iterators

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

Hello, first off sorry if this is not the right issue type, but I could not choose one that seemed to better fit. I tried to search in existing issues with "zip repeat rev" and nothing came up in GitHub. I don't know if it qualifies as a bug, but at least the behavior feels highly unintuitive.

I tried this code:

```rust
fn main() {
    let vec_1 = vec![1; 10];
    
    let zipped_iter = vec_1.iter().zip( std::iter::repeat(0));
    
    println!("Forward");
    
    for (one, zero) in zipped_iter {
        println!("one: {one}, zero: {zero}");
    }
    
    let rev_vec_iter = vec_1.iter().rev();
    let rev_repeat_iter = std::iter::repeat(0).rev();
    
    // Manual reversed zip
    let rev_zipped_iter = rev_vec_iter.zip(rev_repeat_iter);
    
    println!("Backwards");
    
    for (one, zero) in rev_zipped_iter {
        println!("one: {one}, zero: {zero}");
    }
    
    println!("Now it gets tricky");
    
    // This is illegal with the current next_back implementation of Zip
    // Which requires ExactSizeIterator, which is not implemented by
    // std::iter::repeat, so won't compile
    
    let zipped_iter = vec_1.iter().zip( std::iter::repeat(0));
    
    // Cannot call rev here for automatic reversed zip constuction
    for (one, zero) in zipped_iter.rev() {
        println!("one: {one}, zero: {zero}");
    }
}
```

Rust playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=967385983c0fb72c27183385720fea8e

I expected to see this happen: the last iterator construction reversing the Zip iterator works the same as if I zipped two reverse iterator.

Instead, this happened: code does not compile because next_back implementation from Zip (ZipImpl::next_back) has ExactSizeIterator bounds for both iterator being zipped. std::iter::Repeat does not implement that trait. I'm not familiar with Zip internals or iterator internals but it seems it has to do with zip_impl_general_defaults which states:

```rust
        #[inline]
        default fn next_back(&mut self) -> Option<(A::Item, B::Item)>
        where
            A: DoubleEndedIterator + ExactSizeIterator,
            B: DoubleEndedIterator + ExactSizeIterator,
        {
            // The function body below only uses `self.a/b.len()` and `self.a/b.next_back()`
            // and doesn’t call `next_back` too often, so this implementation is safe in
            // the `TrustedRandomAccessNoCoerce` specialization
```

Fails for all rustc versions in playground at the moment

![image](https://user-images.githubusercontent.com/49040125/203384366-5ec88c18-5cf4-4d49-91d9-1229107c0839.png)


### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc --version --verbose
rustc 1.65.0 (897e37553 2022-11-02)
binary: rustc
commit-hash: 897e37553bba8b42751c67658967889d11ecd120
commit-date: 2022-11-02
host: x86_64-unknown-linux-gnu
release: 1.65.0
LLVM version: 15.0.0
```

<!--
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in your
environment. E.g. `RUST_BACKTRACE=1 cargo build`.
-->
<details><summary>Backtrace</summary>
<p>

```
Compiling playground v0.0.1 (/playground)
error[[E0277]](https://doc.rust-lang.org/stable/error-index.html#E0277): the trait bound `std::iter::Repeat<{integer}>: ExactSizeIterator` is not satisfied
  --> src/main.rs:33:24
   |
33 |     for (one, zero) in zipped_iter.rev() {
   |                        ^^^^^^^^^^^ --- required by a bound introduced by this call
   |                        |
   |                        the trait `ExactSizeIterator` is not implemented for `std::iter::Repeat<{integer}>`
   |
   = help: the following other types implement trait `ExactSizeIterator`:
             &mut I
             Args
             ArgsOs
             ArrayChunksMut<'_, T, N>
             ArrayWindows<'_, T, N>
             Box<I, A>
             Chunks<'_, T>
             ChunksExact<'_, T>
           and 108 others
   = note: required for `Zip<std::slice::Iter<'_, {integer}>, std::iter::Repeat<{integer}>>` to implement `DoubleEndedIterator`
note: required by a bound in `rev`

error[[E0277]](https://doc.rust-lang.org/stable/error-index.html#E0277): the trait bound `std::iter::Repeat<{integer}>: ExactSizeIterator` is not satisfied
  --> src/main.rs:33:24
   |
33 |     for (one, zero) in zipped_iter.rev() {
   |                        ^^^^^^^^^^^^^^^^^ the trait `ExactSizeIterator` is not implemented for `std::iter::Repeat<{integer}>`
   |
   = help: the following other types implement trait `ExactSizeIterator`:
             &mut I
             Args
             ArgsOs
             ArrayChunksMut<'_, T, N>
             ArrayWindows<'_, T, N>
             Box<I, A>
             Chunks<'_, T>
             ChunksExact<'_, T>
           and 108 others
   = note: required for `Zip<std::slice::Iter<'_, {integer}>, std::iter::Repeat<{integer}>>` to implement `DoubleEndedIterator`
   = note: required for `Rev<Zip<std::slice::Iter<'_, {integer}>, std::iter::Repeat<{integer}>>>` to implement `Iterator`
   = note: required for `Rev<Zip<std::slice::Iter<'_, {integer}>, std::iter::Repeat<{integer}>>>` to implement `IntoIterator`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to 2 previous errors
```

</p>
</details>