Reputation: 9568
In the following example, MyTrait
extends IntoIterator
but the compiler doesn't recognize it when used in a loop.
pub trait MyTrait: IntoIterator<Item = i32> {
fn foo(&self);
}
pub fn run<M: MyTrait>(my: &M) {
for a in my {
println!("{}", a);
}
}
I get the error:
error[E0277]: `&M` is not an iterator
--> src/lib.rs:6:14
|
6 | for a in my {
| ^^ `&M` is not an iterator
|
= help: the trait `Iterator` is not implemented for `&M`
= note: required because of the requirements on the impl of `IntoIterator` for `&M`
= note: required by `into_iter`
Upvotes: 5
Views: 8407
Reputation: 28075
Only M
implements IntoIterator
, but you're trying to iterate over a &M
, which doesn't have to.
It's not clear what you hope to achieve with run
, but removing the reference might be a start:
pub fn run<M: MyTrait>(my: M) {
for a in my {
println!("{}", a);
}
}
Note that M
itself may be (or contain) a reference, so writing it in this way doesn't mean you can't use it with borrowed data. Here's one way to use run
to iterate over a &Vec
(playground):
impl<I> MyTrait for I
where
I: IntoIterator<Item = i32>,
{
fn foo(&self) {}
}
fn main() {
let v = vec![10, 12, 20];
run(v.iter().copied());
}
This uses .copied()
to turn an Iterator<Item = &i32>
to an Iterator<Item = i32>
.
Upvotes: 4