diff options
Diffstat (limited to 'compiler/rustc_error_codes/src/error_codes/E0706.md')
-rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0706.md | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0706.md b/compiler/rustc_error_codes/src/error_codes/E0706.md new file mode 100644 index 000000000..d379b8a23 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0706.md @@ -0,0 +1,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 |