diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-11-18 12:34:22 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-11-18 15:23:05 -0800 |
| commit | e565329144fec8ab2aa87afa170c41dc17ad018e (patch) | |
| tree | b8a2036dd6b9eb342a476acf4d293f692703aaa8 /src/librustc_error_codes | |
| parent | a7678779a168d7b49cc22b073c8b68feb6d02d99 (diff) | |
Add error code documentation
Diffstat (limited to 'src/librustc_error_codes')
| -rw-r--r-- | src/librustc_error_codes/error_codes.rs | 2 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0706.md | 78 |
2 files changed, 79 insertions, 1 deletions
diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 428cecf13a3..325b79ba25f 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -381,6 +381,7 @@ E0700: include_str!("./error_codes/E0700.md"), E0701: include_str!("./error_codes/E0701.md"), E0704: include_str!("./error_codes/E0704.md"), E0705: include_str!("./error_codes/E0705.md"), +E0706: include_str!("./error_codes/E0706.md"), E0712: include_str!("./error_codes/E0712.md"), E0713: include_str!("./error_codes/E0713.md"), E0714: include_str!("./error_codes/E0714.md"), @@ -595,7 +596,6 @@ E0744: include_str!("./error_codes/E0744.md"), E0696, // `continue` pointing to a labeled block // E0702, // replaced with a generic attribute input check E0703, // invalid ABI - E0706, // `async fn` in trait // E0707, // multiple elided lifetimes used in arguments of `async fn` E0708, // `async` non-`move` closures with parameters are not currently // supported diff --git a/src/librustc_error_codes/error_codes/E0706.md b/src/librustc_error_codes/error_codes/E0706.md new file mode 100644 index 00000000000..1eb1271a9e8 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0706.md @@ -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 \ No newline at end of file |
