summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_error_codes/src/error_codes/E0706.md
blob: d379b8a2384c675ece632d056a724438c3a5dc47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
`async fn`s are not yet supported in traits in Rust.

Erroneous code example:

```compile_fail,edition2018
trait T {
    // Neither case is currently supported.
    async fn foo() {}
    async fn bar(&self) {}
}
```

`async fn`s return an `impl Future`, making the following two examples
equivalent:

```edition2018,ignore (example-of-desugaring-equivalence)
async fn foo() -> User {
    unimplemented!()
}
// The async fn above gets desugared as follows:
fn foo(&self) -> impl Future<Output = User> + '_ {
    unimplemented!()
}
```

But when it comes to supporting this in traits, there are [a few implementation
issues][async-is-hard]. One of them is returning `impl Trait` in traits is not
supported, as it would require [Generic Associated Types] to be supported:

```edition2018,ignore (example-of-desugaring-equivalence)
impl MyDatabase {
    async fn get_user(&self) -> User {
        unimplemented!()
    }
}

impl MyDatabase {
    fn get_user(&self) -> impl Future<Output = User> + '_ {
        unimplemented!()
    }
}
```

Until these issues are resolved, you can use the [`async-trait` crate], allowing
you to use `async fn` in traits by desugaring to "boxed futures"
(`Pin<Box<dyn Future + Send + 'async>>`).

Note that using these trait methods will result in a heap allocation
per-function-call. This is not a significant cost for the vast majority of
applications, but should be considered when deciding whether to use this
functionality in the public API of a low-level function that is expected to be
called millions of times a second.

You might be interested in visiting the [async book] for further information.

[`async-trait` crate]: https://crates.io/crates/async-trait
[async-is-hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/
[Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
[async book]: https://rust-lang.github.io/async-book/07_workarounds/06_async_in_traits.html