How to get (or convert) the return value from std::future::Future<Output = value>, which is an opaque type?

I am developing a project using crate iced, and the application trait require a method implemented with the following signature:
fn new(_flags: ()) -> (Memories, Command<Message>) {}

However, I tried to add an async function in the required method and the compiler made an argument of unable to complete the type conversion between impl std::future::Future<Output = Result<Value, _>> (which the async function returns) and Value (which I need it for the return value of new()).

Here is the build info:

PS C:\graduate> cargo build
   Compiling graduate v0.1.0 (C:\graduate)
error[E0308]: mismatched types
   --> src\main.rs:113:27
    |
113 |                 idxtable: exchange::getidx(cli, format!("{}{}", url_prefix, "index.toml"), idxdir),
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Value`, found opaque type
    |
note: while checking the return type of the `async fn`
   --> src\exchange.rs:10:66
    |
10  | pub async fn getidx<E>(cli: Client, url: String, dir: String) -> Result<Value, E> {
    |                                                                  ^^^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected enum `Value`
            found opaque type `impl std::future::Future<Output = Result<Value, _>>`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `graduate` due to previous error

This is my first time opening a topic, so please let me know if there is anything to add or explain.

Without knowing iced, I assume that the iced::application::Application trait requires the new method to be non-async.

Note that when you write an async fn, this effectively means that the function will implicitly have a different return type (it will return an opaque/unnameable type which implements the std::future::Future trait). Thus making a function async changes its return type.

You must provide a non-async implementations for non-async methods. Does that help?

Side note: Rust doesn't fully support async methods in traits yet. So trait methods are often non-async or if they are async, they either return a named future or a boxed dyn future.

1 Like

That really helped.
I found the future trait can be inplemented through the perform() method.
Thanks a lot.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.