Hello there,
I can't figure out the correct lifetime annotations for my code.
My goal is to have a vector of Tests, where each test has a name and a function. Each test function takes two parameters: A reference with static lifetime, and a mutable reference which can only be used during the invocation of the function.
The test functions are async internally, but the external interface can just as well be sync. Everything worked well when the test functions would only take a single static parameter. But as soon as I added the second parameter, I run into the error.
How do I need to change my code, that it compiles again?
Thank you
use core::fmt::Debug;
use core::future::Future;
use futures::executor::block_on;
struct StaticParam;
struct Param;
struct Test<F> {
name: &'static str,
fun: F,
}
impl<F> Test<F> {
const fn new(name: &'static str, fun: F) -> Self {
Self { name, fun }
}
}
trait Testable {
fn name(&self) -> &'static str;
fn run(&self, st: &'static StaticParam, nsta: &mut Param) -> Result<String, String>;
}
impl<Fut, F, S: Debug, E: Debug> Testable for Test<F>
where
for<'a> F: Fn(&'static StaticParam, &'a mut Param) -> Fut + 'a,
Fut: Future<Output = Result<S, E>>,
{
fn name(&self) -> &'static str {
self.name
}
fn run(&self, st: &'static StaticParam, nsta: &mut Param) -> Result<String, String> {
match block_on((self.fun)(st, nsta)) {
Ok(p) => {
Ok(format!("{:?}", p))
}
Err(e) => {
Err(format!("{:?}", e))
}
}
}
}
const TESTS: &[&dyn Testable] = &[
&Test::new("i2c", test_i2c),
&Test::new("co2", test_co2),
];
async fn test_i2c(_sta: &'static StaticParam, _nsta: &mut Param) -> Result<(), ()> {
todo!()
}
async fn test_co2(_sta: &'static StaticParam, _nsta: &mut Param) -> Result<(), ()> {
todo!()
}
static STA: StaticParam = StaticParam;
fn main() -> ! {
let mut nsta = Param;
for test in TESTS {
test.run(&STA, &mut nsta);
}
loop {}
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:45:5
|
45 | &Test::new("i2c", test_i2c),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected opaque type `impl for<'a> futures::Future<Output = Result<(), ()>>`
found opaque type `impl futures::Future<Output = Result<(), ()>>`
= help: consider `await`ing on both `Future`s
= note: distinct uses of `impl Trait` result in different opaque types
error[E0308]: mismatched types
--> src/main.rs:46:5
|
46 | &Test::new("co2", test_co2),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected opaque type `impl for<'a> futures::Future<Output = Result<(), ()>>`
found opaque type `impl futures::Future<Output = Result<(), ()>>`
= help: consider `await`ing on both `Future`s
= note: distinct uses of `impl Trait` result in different opaque types
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (bin "playground") due to 2 previous errors