Hey, im trying to write a wrapper for an async function. It should produce a new function and return that function to be called later on. You can see the playground on how exactly i imagine it to work. But the error im getting just confuses me. Can someone explain me what im doing wrong and maybe propose a fix? Thanks in advance!
error[E0308]: mismatched types
--> src/main.rs:48:13
|
48 | let c = wrap_function(some_function);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected opaque type `impl for<'a> Future<Output = Result<Data, Error>>`
found opaque type `impl Future<Output = Result<Data, Error>>`
= help: consider `await`ing on both `Future`s
= note: distinct uses of `impl Trait` result in different opaque types
note: the lifetime requirement is introduced here
--> src/main.rs:31:28
|
31 | Func: Fn(&mut Conn) -> Fut + Send + Sync + 'static,
| ^^^
There's currently a new feature on nightly which addresses exactly your problem. Read here. Until this is on stable I recommend using this crate.
EDIT: Sorry, I was too fast... as the blog post also mentions you cannot yet put additional bounds to the future, but you obviously want that... but async_fn_traits should still solve your problem.
struct SomeUnnameableFuture<'a>(SomeUnnameableAsyncState<'a>);
impl Future for SomeUnnameableFuture<'_> {
type Output = Result<Data, Error>;
// ...
}
// Callers see an opaque `impl Future<Output=...>`
fn some_function<'c>(_conn: &'c mut Conn) -> SomeUnnameableFuture<'c> {
Note that for every input lifetime 'c, you get a different output type SomeUnnameableFuture<'c>. Even though they all only differ by the lifetime, they're still different types.
Type parameters like Fut represent a single type, so the bounds only accept functions/closures that always return the same type.
"implementation of Fn is not general enough" is the relevant error. Sadly you more or less just have to have experience to know what it's talking about, and it comes after another less helpful[1] error to boot.