'Contradictory error messages calling .any() on &dyn Iterator vs &mut dyn Iterator

MCVE (simplified from real code where I may return a raw vec.iter(), or a vec.iter().filter() based on some conditions):

let input = vec![1,2,3];
let dyn_iter: &dyn Iterator<Item = &i32> = &input.iter();
let result = dyn_iter.any(|x| *x == 2);

Gives error:

error: the `any` method cannot be invoked on a trait object
    --> src/main.rs:19:37
     |
19   |     let result: Vec<i32> = dyn_iter.any(|x| x == 2);
     |                                     ^^^
     |
    ::: ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2507:15
     |
2507 |         Self: Sized,
     |               ----- this has a `Sized` requirement
     |
     = note: you need `&mut dyn Iterator<Item = &i32>` instead of `&dyn Iterator<Item = &i32>`

However, if I change & to &mut, then I get the OPPOSITE error:

let input = vec![1,2,3];
let dyn_iter: &mut dyn Iterator<Item = &i32> = &mut input.iter();
let result = dyn_iter.any(|x| *x == 2);

Gives:

error: the `any` method cannot be invoked on a trait object
    --> src/main.rs:19:37
     |
19   |     let result: Vec<i32> = dyn_iter.any(|x| x == 2);
     |                                     ^^^
     |
    ::: ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2507:15
     |
2507 |         Self: Sized,
     |               ----- this has a `Sized` requirement
     |
     = note: you need `&dyn Iterator<Item = &i32>` instead of `&mut dyn Iterator<Item = &i32>`

Here are the last lines of the error messages for comparison. Note how they are exactly contradictory!

     = note: you need `&mut dyn Iterator<Item = &i32>` instead of `&dyn Iterator<Item = &i32>`
     = note: you need `&dyn Iterator<Item = &i32>` instead of `&mut dyn Iterator<Item = &i32>`

I found a similar question: Why does adding mut to passed Iterator reference solve this?, but he is using .map() instead of .any(). When I use .map(), it works just fine:

let input = vec![1,2,3];
let dyn_iter: &mut dyn Iterator<Item = &i32> = &mut input.iter();
let result: Vec<i32> = dyn_iter.map(|x| x+1).collect();

This runs without errors. So it seems the problem is specific to the any() method? What's going on?



Solution 1:[1]

The compiler error message is really misleading there... the answer is as simple as Iterator::any has a Self: Sized bound so it is not trait object safe and not usable from a trait object.

The behavior is trivially reproducible, playground:

pub trait Foo {
    fn bar(&mut self) where Self: Sized;
}


impl Foo for Vec<u32> {
    fn bar(&mut self) where Self: Sized {}
}

fn main() {
    let input = vec![1,2,3];
    let dyn_iter: &mut dyn Foo = &mut input;
    let result = dyn_iter.bar();
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 mental