Change:
we currently emit We should tell people that trait functions are not possible , and possibly point them to . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Created

Discussion:
E0701: include_str!("./error_codes/E0701.md"), E0704: include_str!("./error_codes/E0704.md"), E0705: include_str!("./error_codes/E0705.md"), <ins> E0706: include_str!("./error_codes/E0706.md"), </ins> 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 <del> E0706, // `async fn` in trait </del> //  E0707, // multiple elided lifetimes used in arguments of `async fn` E0708, // `async` non-`move` closures with parameters are not currently // supported

<ins> `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 </ins>

fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) { if asyncness.is_async() { <del> struct_span_err!(self.session, span, E0706, "trait fns cannot be declared `async`").emit() </del> <ins> struct_span_err!(self.session, span, E0706, "trait fns cannot be declared `async`") .note("`async` trait functions are not currently supported") .note("consider using the `async-trait` crate:  https://crates.io/crates/async-trait") .emit(); </ins> } }

<ins> // edition:2018 trait T { async fn foo() {} //~ ERROR trait fns cannot be declared `async` async fn bar(&self) {} //~ ERROR trait fns cannot be declared `async` } fn main() {} </ins>

<ins> error[E0706]: trait fns cannot be declared `async` --> $DIR/async-trait-fn.rs:3:5 | LL |     async fn foo() {} |     ^^^^^^^^^^^^^^^^^ | = note: `async` trait functions are not currently supported = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error[E0706]: trait fns cannot be declared `async` --> $DIR/async-trait-fn.rs:4:5 | LL |     async fn bar(&self) {} |     ^^^^^^^^^^^^^^^^^^^^^^ | = note: `async` trait functions are not currently supported = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0706`. </ins>

| LL |     async fn foo() {} |     ^^^^^^^^^^^^^^^^^ <ins> | = note: `async` trait functions are not currently supported = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait </ins> error: aborting due to 10 previous errors <del> For more information about this error, try `rustc --explain E0670`. </del> <ins> Some errors have detailed explanations: E0670, E0706. For more information about an error, try `rustc --explain E0670`. </ins>