The `Zip` iterator does not update the underlying iterator correctly in its `TrustedLen` specialization.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I tried this code:
pub fn using_each() {
let mut it = 0..4;
it.by_ref().zip(0..2).for_each(|_| {});
println!("{:?}", it);
}
pub fn using_loop() {
let mut it = 0..4;
for _ in it.by_ref().zip(0..2) {}
println!("{:?}", it);
}
pub fn using_each_dyn() {
let mut it = 0..4;
(&mut it as &mut dyn Iterator<Item = i32>).zip(0..2).for_each(|_| {});
println!("{:?}", it);
}
pub fn using_loop_dyn() {
let mut it = 0..4;
for _ in (&mut it as &mut dyn Iterator<Item = i32>).zip(0..2) {}
println!("{:?}", it);
}
fn main() {
using_each();
using_loop();
using_each_dyn();
using_loop_dyn();
}
I expected all four functions to behave identically, but instead the above code outputs:
2..4
3..4
3..4
3..4
This occurs because:
- In the general case, the
Zipiterator will call.next()on the first iterator to check if the value isNone, and then call.next()on the second iterator. This means that if the second iterator is shorter, then the first iterator will have.next()called one past the length of the second iterator. - In the
TrustedLenspecialization ofZip'sfold()method, if the second iterator is shorter, then both iterators have their.next()called exactly equal to that second iterator's length.
https://github.com/rust-lang/rust/blob/231257f583c6e782da2e642ad007fca4e76779d6/library/core/src/iter/adapters/zip.rs#L666-L695
This mismatch in behavior seems undesirable.
Discovered in #143966.
Meta
Reproducible on the playground with version 1.90.0-nightly (2025-07-15 3014e79f9c8d5510ea7b)
@rustbot labels +A-iterators +A-specialization
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with library/core/src/iter/adapters/zip.rs around the TrustedLen-specialized fold implementation and reproduce the four iterator examples from the issue. Compare the specialized and general Zip consumption paths, then verify that the chosen behavior is consistent and covered by an appropriate regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100