Function that returns impl Iterator<Item = Box<dyn Iterator<Item = i32>>>

I found a similar discussion here, but in my case it's about the return type.
I'm trying to return impl Iterator<Item = Box<dyn Iterator<Item = i32>>> from a function. What am I doing wrong to make f2 compile?

use std::iter::once;
// This works..
fn f1() -> Box<dyn Iterator<Item = i32>> {
    Box::new(once(1))
}
// This doesn't compile
fn f2() -> impl Iterator<Item = Box<dyn Iterator<Item = i32>>> {
    once(Box::new(once(1)))
}

Hmm, looks like explicit coercion is needed to give the compiler an extra hint that it can and needs to coerce Box<Once<{integer}>> to Box<dyn Iterator<Item = i32>>:

use std::iter::once;
// This works..
fn f1() -> Box<dyn Iterator<Item = i32>> {
    Box::new(once(1))
}
// This doesn't compile
fn f2() -> impl Iterator<Item = Box<dyn Iterator<Item = i32>>> {
    once(Box::new(once(1)) as _)
}

Playground.

1 Like

It also works if you call f1 in f2.

use std::iter::once;
// This works..
fn f1() -> Box<dyn Iterator<Item = i32>> {
    Box::new(once(1))
}
// This also compiles
fn f2() -> impl Iterator<Item = Box<dyn Iterator<Item = i32>>> {
    once(f1())
}
1 Like

Thank you very much, exactly what I was looking for. I revisited the chapter in the rust book about coercion. Interesting that _ can be used here.

Yes, a neat little trick @quinedot showed me :slightly_smiling_face: :

I guess you can use the _ placeholder here, because the compiler can infer the type it should coerce to from your function signature's return type. It just needs a nudge to do the coercion, because of the added indirection from the outer call to once. The topic I linked was me struggling to do trait object coercion with collections, which boils down to the same behaviour of Rust's type inference that you experienced with your problem here, I'd say.

1 Like

Thanks for the link. Seeing another example makes the case even more clear.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.