I have a function that returns an impl Trait
so I don't have access to the concrete return type. I need to use the return value of that function as an associated type in a trait. How do I do that?
Here is a simplified example:
fn f() -> impl Iterator<Item = u8> {
std::iter::empty()
}
struct S;
impl IntoIterator for S {
type Item = u8;
type IntoIter = (); // What can I write here ?
fn into_iter(self) -> Self::IntoIter {
f()
}
}
Is it even possible to do (without resorting to boxing the iterator)?
Unfortunately, you can't. At least not yet.
There is an RFC, Named existentials and impl Trait variable declarations (tracking issue), which would allow you to declare a public type name at the module level, whose type definition is inferred from how it used within the module. Users of the module can refer to this type by its public name and it can be used as an associated type.
It's difficult to guess when a new feature will stabilise and in the meantime there really aren't many good options. Aside from things that might only work because of specifics of your use-case, the general workaround is to use a trait object:
impl IntoIterator for S {
type Item = u8;
type IntoIter = Box<dyn Iterator<Item = u8>>;
fn into_iter(self) -> Self::IntoIter {
Box::new(f())
}
}
If it is acceptable to use nightly features, you can help test out the RFC before it stabilises:
#![feature(existential_type)]
impl IntoIterator for S {
type Item = u8;
existential type IntoIter: Iterator<Item = u8>;
fn into_iter(self) -> Self::IntoIter {
f()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With