about summary refs log tree commit diff
path: root/src/librustc_error_codes/error_codes
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-20 14:04:12 +0000
committerbors <bors@rust-lang.org>2019-11-20 14:04:12 +0000
commitb9cf5417892ef242c783ef963deff5436205b0f6 (patch)
tree0a875cafe855dc3b67841e2846155b2160ea0154 /src/librustc_error_codes/error_codes
parentea540b0892ed6b62d170c7f0a9aa362e590de8b4 (diff)
parentebd0ef9a39cbec962ed246d523186a8b88ccb351 (diff)
downloadrust-b9cf5417892ef242c783ef963deff5436205b0f6.tar.gz
rust-b9cf5417892ef242c783ef963deff5436205b0f6.zip
Auto merge of #66571 - Centril:rollup-41tn2fw, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #65665 (Update Source Code Pro and include italics)
 - #66478 (rustc_plugin: Remove the compatibility shim)
 - #66497 (Fix #53820)
 - #66526 (Add more context to `async fn` trait error)
 - #66532 (Generate DWARF address ranges for faster lookups)
 - #66546 (Remove duplicate function)
 - #66548 ([RISCV] Disable Atomics on all Non-A RISC-V targets)
 - #66553 (remove HermitCore leftovers from sys/unix)

Failed merges:

r? @ghost
Diffstat (limited to 'src/librustc_error_codes/error_codes')
-rw-r--r--src/librustc_error_codes/error_codes/E0706.md57
1 files changed, 57 insertions, 0 deletions
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..bee9219af7c
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0706.md
@@ -0,0 +1,57 @@
+ `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