'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 |