Reputation: 138
I've got a scenario where I want to pass a function pointer (or closure) that takes a mutable reference to a struct, as a way of letting the caller initialize that struct for me.
The (very simplified) code looks like this:
use std::future::Future;
struct Data {
value: u32
}
async fn initialize(data: &mut Data) {
// ... do some async work ...
data.value = 1;
}
fn do_work<Fut>(init: fn(&mut Data) -> Fut)
where
Fut: Future<Output = ()>,
{
pollster::block_on(async {
let mut data = Data { value:0 };
init(&mut data).await;
// ... do other stuff with `data`
})
}
fn main() {
do_work(initialize);
}
And I get the compiler error:
error[E0308]: mismatched types
--> src/main.rs:29:13
|
29 | do_work(initialize);
| ------- ^^^^^^^^^^ one type is more general than the other
| |
| arguments to this function are incorrect
|
= note: expected fn pointer `for<'a> fn(&'a mut Data) -> _`
found fn item `for<'a> fn(&'a mut Data) -> impl Future<Output = ()> {initialize}`
note: function defined here
--> src/main.rs:17:4
|
17 | fn do_work<Fut>(init: fn(&mut Data) -> Fut)
| ^^^^^^^ --------------------------
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
but I can not find where I've gone wrong. I'm suspecting there's something whacky happening with Higher-Ranked Trait Bounds since there's a for<'a>
in there, but I can't figure out why it's not correct.
If I don't make initialize
async, it works just as expected. Maybe there's something going on with Future<Output = ()>
?
Edit:
A similar question is "Expected fn item, found a different fn item" when working with function pointers, but as @PitaJ pointed out this is not the same thing as in this case I've got a fn item
and a fn pointer
and not two fn item
s, and here there's a generic function output.
Upvotes: 1
Views: 53