Chain is not ExactSizeIterator?

Okay, I've gotta be missing something. Why does this instance not appear to exist in std::iter?

impl<A, B> ExactSizeIterator for Chain<A, B>
  where A: ExactSizeIterator, B: ExactSizeIterator {}

Is it the mixture of saturating and checked addition in the impl for size_hint?

1 Like

Yes:

use std::iter::ExactSizeIterator;

fn main() {
    println!("{:?}", (0usize..(1<<63)).chain(0usize..1<<63).size_hint());
    println!("{:?}", (0usize..(1<<63)).len());
}

The docs say that ExactSizeIterator guarantees that the size fits in an usize and no adaptor that extends another by just one element or more can do that, unfortunately.

I don't know, this is maybe something we can relax with careful thought but for now it's best to stick to the documented rules.

3 Likes

Ah, the curse of fixed-width integer types -- the sum of two sizes may not be representable. Should've thought of that. Thanks!

Hm, this kinda sucks, but it's understandable. Add me to the list of people who'd like to see a better solution than just using size_hint() (when you know your chained iterators will never be near as long as usize::MAX).

What exactly do you need ExactSizeIterator for? We will soon have have a TrustedLen trait (primarily for optimizations):

https://github.com/rust-lang/rust/issues/37572

Actually I realized not long after posting to this thread that I want to filter the elements of the iterator I wanted this for. So in the end I wouldn't be able to use it anyway..