Add error code documentation

This commit is contained in:
Esteban Küber 2019-11-18 12:34:22 -08:00
parent a7678779a1
commit e565329144
4 changed files with 82 additions and 2 deletions

View file

@ -0,0 +1,78 @@
`async fn`s are not yet supported 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 normally 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 which is that 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], which allows you to use
this feature by sidesteping the language feature issue by desugaring to "boxed futures"
(`Pin<Box<dyn Future + Send + 'async>>`):
```edition2018,ignore (example-of-desugaring-equivalence)
#[async_trait]
impl MyDatabase {
async fn get_user(&self) -> User {
unimplemented!()
}
}
// The annotated impl above gets desugared as follows:
impl MyDatabase {
fn get_user<'async>(
&'async self,
) -> Pin<Box<dyn std::future::Future<Output = User> + Send + 'async>>
where
Self: Sync + 'async,
{
unimplemented!()
}
}
```
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