]> git.lizzy.rs Git - rust.git/commitdiff
Add error code documentation
authorEsteban Küber <esteban@kuber.com.ar>
Mon, 18 Nov 2019 20:34:22 +0000 (12:34 -0800)
committerEsteban Küber <esteban@kuber.com.ar>
Mon, 18 Nov 2019 23:23:05 +0000 (15:23 -0800)
src/librustc_error_codes/error_codes.rs
src/librustc_error_codes/error_codes/E0706.md [new file with mode: 0644]
src/test/ui/async-await/async-trait-fn.stderr
src/test/ui/async-await/edition-deny-async-fns-2015.stderr

index 428cecf13a3b01beedea67c5eb77f0f4a70d41dc..325b79ba25f68626621ed737edcadcc2c485381a 100644 (file)
 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"),
     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 (file)
index 0000000..1eb1271
--- /dev/null
@@ -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
index fb6e0c57d6a0dd3f3400d8597a1fc7d5b04d63b2..9acfa2cc0691294b5de863e4bcb7d1d0aabe96b7 100644 (file)
@@ -18,3 +18,4 @@ LL |     async fn bar(&self) {}
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0706`.
index dc1c891c591eb80933de2a4710845a5826588b15..bb09ee9a9329633eac10d4738506d82582ca4d98 100644 (file)
@@ -63,4 +63,5 @@ LL |     async fn foo() {}
 
 error: aborting due to 10 previous errors
 
-For more information about this error, try `rustc --explain E0670`.
+Some errors have detailed explanations: E0670, E0706.
+For more information about an error, try `rustc --explain E0670`.