I have a use case where I need to specify a dummy Future to make a type concrete. The use case is I have a struct which takes a generic parameter, which is a Future:
let thing = Thing<Fut>::some_method().await?;
some_method
is a method on Thing
which does not use the Fut
at all, but the compiler complains because of the compiler limitations such that the type can't be inferred and is necessary because of the async block.
Since I need a concrete sized thing for Fut
, I was hoping there was something in futures_util that I could use. Right now, this is my very bad approach:
use futures::Future;
use std::pin::Pin;
struct Thing<Fut>
where
for<'b> Fut: Future<Output = ()> + Send + 'b,
{
callback: dyn Fn() -> Fut + Send + Sync,
}
impl<Fut> Thing<Fut> where for<'b> Fut: Future<Output = ()> + Send + 'b {
async fn some_method(a: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("I am some_method with value {}", a);
Ok(())
}
}
struct Dummy {
}
impl Future for Dummy {
type Output = ();
fn poll(
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
unimplemented!()
}
}
#[tokio::main]
async fn main() {
// this fails
Thing::some_method(3).await.unwrap();
// this works
//Thing::<Dummy>::some_method(3).await.unwrap();
}
Is there something I can leverage here to make such a dummy value available?
Here is a minimal playground example: playground link
The error:
error[E0698]: type inside `async` block must be known in this context
--> src/main.rs:33:5
|
33 | Thing::some_method(3).await.unwrap();
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `Fut`
|
note: the type is part of the `async` block because of this `await`
--> src/main.rs:33:26
|
33 | Thing::some_method(3).await.unwrap();
| ^^^^^^
If you uncomment the success line, it will remove the error.
You can use std::future::Ready
(or probably Pending
alternatively). This is the type returned by the std::future::ready
function.
use std::future::Ready;
type Dummy = Ready<()>;
#[tokio::main]
async fn main() {
Thing::<Dummy>::some_method(3).await.unwrap();
}
But if this function has no dependence on Fut
, then I'd question why it's an associated function on Thing
in the first place. Maybe it should be a free-standing function instead.