I'm trying to pass a function as one of the arguments to another function and I'm running into a one type is more general than the other
error.
use std::future::Future;
async fn constraint<A, Fut, L>(args: A, lambda: L)
where
A: 'static + Send,
Fut: Future<Output = ()> + 'static,
L: Fn(&A) -> Fut + 'static,
{
lambda(&args).await;
}
fn main() {
constraint("hello".to_string(), lambda);
}
async fn lambda(_: &String) -> () {}
Here is the error message:
error[E0308]: mismatched types
--> src/main.rs:13:5
|
13 | constraint("hello".to_string(), lambda);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a> <for<'a> fn(&'a String) -> impl Future<Output = ()> {lambda} as FnOnce<(&'a String,)>>`
found trait `for<'a> <for<'a> fn(&'a String) -> impl Future<Output = ()> {lambda} as FnOnce<(&'a String,)>>`
note: the lifetime requirement is introduced here
--> src/main.rs:7:18
|
7 | L: Fn(&A) -> Fut + 'static,
| ^^^
For more information about this error, try `rustc --explain E0308`.
I don’t want to change the lambda function because I want to be able to call it multiple times in a while loop with a second argument from an input stream, but I can change constraint function.
So far I tried adding a lifetime to the constraint function but I'm not sure if that is on the right path since there should already be a static lifetime on A:
async fn constraint<'a, A, Fut, L>(args: A, lambda: L)
where
A: 'static + Send,
Fut: Future<Output = ()> + 'static,
L: Fn(&'a A) -> Fut + 'static,
{
lambda(&args).await;
}
Corresponding error:
|
3 | async fn constraint<'a, A, Fut, L>(args: A, lambda: L)
| -- lifetime `'a` defined here
...
9 | lambda(&args).await;
| -------^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `args` is borrowed for `'a`
10 | }
| - `args` dropped here while still borrowed
Also tried to move the argument but got the same error:
use std::future::Future;
async fn constraint<A, Fut, L>(args: A, lambda: L)
where
A: 'static + Send,
Fut: Future<Output = ()> + 'static,
L: Fn(&A) -> Fut + 'static,
{
async move {
lambda(&args).await;
};
}
fn main() {
constraint("hello".to_string(), lambda);
}
async fn lambda(_: &String) -> () {}