TrustedLen Iterator from an Iterator that is not implementing TrustedLen

Advertisements

I’m new to Rust, so this may be a naive question, but I was looking at the TrustedLen trait and was confused. It describes that a TrustedLen iterator
"reports a size hint where it is either exact (lower bound is equal to upper bound), or the upper bound is None." I was curious about the cases where we create a TrustedLen iterator, from another iterator that doesn’t implement the TrustedLen.

pub fn main() -> () {
    let v = vec![1, 2, 3, 4, 5];
    
    let (lower, upper) = v.iter().filter(|num| {*num % 2 == 0}).take(2).size_hint();
    println!("({},{})", lower, upper.unwrap());
}

This produces the message

(0,2)

Here the lower bound doesn’t match the upper bound, because of the filter predicate, however I’m calling size_hint on a Take iterator which implements TrustedLen.

>Solution :

Take implements TrustedLen conditionally only when the inner iterator is TrustedLen. In this case, Filter is not, so the iterator is not TrustedLen:

#![feature(trusted_len)]

fn require_trusted_len(_: impl std::iter::TrustedLen) {}

fn main() {
    let v = vec![1, 2, 3, 4, 5];
    
    let iter = v.iter().filter(|num| {*num % 2 == 0}).take(2);
    require_trusted_len(iter);
}

Yields:

error[E0277]: the trait bound `Filter<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:8:32: 8:37]>: TrustedLen` is not satisfied
 --> src/main.rs:9:25
  |
9 |     require_trusted_len(iter);
  |     ------------------- ^^^^ the trait `TrustedLen` is not implemented for `Filter<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:8:32: 8:37]>`
  |     |
  |     required by a bound introduced by this call
  |
  = help: the following other types implement trait `TrustedLen`:
            &mut I
            ArrayChunksMut<'_, T, N>
            Chunks<'_, T>
            ChunksExact<'_, T>
            ChunksExactMut<'_, T>
            ChunksMut<'_, T>
            Cloned<I>
            Copied<I>
          and 44 others
  = note: required for `std::iter::Take<Filter<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:8:32: 8:37]>>` to implement `TrustedLen`
note: required by a bound in `require_trusted_len`
 --> src/main.rs:3:32
  |
3 | fn require_trusted_len(_: impl std::iter::TrustedLen) {}
  |                                ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `require_trusted_len`

Leave a Reply Cancel reply