Reputation: 493
I want to do the following
struct Stored<F: Future<Output = ()>> {
f: Option<F>,
}
impl<F: Future<Output = ()>> Stored<F> {
fn store(&mut self, f: F) {
let f = async {};
self.f = Some(f);
}
}
But it gives me the error:
expected type parameter `F`
found opaque type `impl futures::Future<Output = ()>`
type parameters must be constrained to match other types
I could solve it boxing the future, but if the method store
was the only place I stored this future, there would be no need to do that, because all the future blocks would be always the same type. How could I do it?
Upvotes: 1
Views: 574
Reputation: 168958
This doesn't work because F
is a generic type provided from outside of the Stored
type, but the actual type of the future is an unnamed type provided from within the store
associated function (created by async {}
). There is no possible way that F
can be specified to be the correct type.
The way this is usually handled is to create a dedicated, nameable type implementing Future
. In this trivial case, that could be std::future::Ready<()>
:
struct Stored {
f: Option<std::future::Ready<()>>,
}
impl Stored {
fn store(&mut self) {
self.f = Some(std::future::ready(()));
}
}
If the type of the future actually does come from outside of the type, then you just need to adjust your code to use f
directly instead of discarding it and using async {}
:
use std::future::Future;
struct Stored<F> {
f: Option<F>,
}
impl<F: Future> Stored<F> {
fn store(&mut self, f: F) {
self.f = Some(f);
}
}
Upvotes: 2