|
6 | 6 | //!
|
7 | 7 | //! <br>
|
8 | 8 | //!
|
9 |
| -//! <h5>Type erasure for async trait methods</h5> |
| 9 | +//! <h4>Type erasure for async trait methods</h4> |
10 | 10 | //!
|
11 |
| -//! The initial round of stabilizations for the async/await language feature in |
12 |
| -//! Rust 1.39 did not include support for async fn in traits. Trying to include |
13 |
| -//! an async fn in a trait produces the following error: |
| 11 | +//! The stabilization of async functions in traits in Rust 1.75 did not include |
| 12 | +//! support for using traits containing async functions as `dyn Trait`. Trying |
| 13 | +//! to use dyn with an async trait produces the following error: |
14 | 14 | //!
|
15 |
| -#![cfg_attr(not(native_async_fn_in_trait), doc = "```compile_fail")] |
16 |
| -#![cfg_attr(native_async_fn_in_trait, doc = "```")] |
17 |
| -//! trait MyTrait { |
18 |
| -//! async fn f() {} |
| 15 | +//! ```compile_fail |
| 16 | +//! pub trait Trait { |
| 17 | +//! async fn f(&self); |
19 | 18 | //! }
|
20 |
| -#![doc = "```"] |
| 19 | +//! |
| 20 | +//! pub fn make() -> Box<dyn Trait> { |
| 21 | +//! unimplemented!() |
| 22 | +//! } |
| 23 | +//! ``` |
21 | 24 | //!
|
22 | 25 | //! ```text
|
23 |
| -//! error[E0706]: trait fns cannot be declared `async` |
24 |
| -//! --> src/main.rs:4:5 |
| 26 | +//! error[E0038]: the trait `Trait` cannot be made into an object |
| 27 | +//! --> src/main.rs:5:22 |
| 28 | +//! | |
| 29 | +//! 5 | pub fn make() -> Box<dyn Trait> { |
| 30 | +//! | ^^^^^^^^^ `Trait` cannot be made into an object |
| 31 | +//! | |
| 32 | +//! note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> |
| 33 | +//! --> src/main.rs:2:14 |
25 | 34 | //! |
|
26 |
| -//! 4 | async fn f() {} |
27 |
| -//! | ^^^^^^^^^^^^^^^ |
| 35 | +//! 1 | pub trait Trait { |
| 36 | +//! | ----- this trait cannot be made into an object... |
| 37 | +//! 2 | async fn f(&self); |
| 38 | +//! | ^ ...because method `f` is `async` |
| 39 | +//! = help: consider moving `f` to another trait |
28 | 40 | //! ```
|
29 | 41 | //!
|
30 |
| -//! This crate provides an attribute macro to make async fn in traits work. |
| 42 | +//! This crate provides an attribute macro to make async fn in traits work with |
| 43 | +//! dyn traits. |
31 | 44 | //!
|
32 | 45 | //! Please refer to [*why async fn in traits are hard*][hard] for a deeper
|
33 | 46 | //! analysis of how this implementation differs from what the compiler and
|
34 |
| -//! language hope to deliver in the future. |
| 47 | +//! language deliver natively. |
35 | 48 | //!
|
36 | 49 | //! [hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/
|
37 | 50 | //!
|
|
43 | 56 | //! using async fn in a trait.
|
44 | 57 | //!
|
45 | 58 | //! The only thing to notice here is that we write an `#[async_trait]` macro on
|
46 |
| -//! top of traits and trait impls that contain async fn, and then they work. |
| 59 | +//! top of traits and trait impls that contain async fn, and then they work. We |
| 60 | +//! get to have `Vec<Box<dyn Advertisement + Sync>>` or `&[&dyn Advertisement]`, |
| 61 | +//! for example. |
47 | 62 | //!
|
48 | 63 | //! ```
|
49 | 64 | //! use async_trait::async_trait;
|
|
111 | 126 | //! > ☑ Associated types;<br>
|
112 | 127 | //! > ☑ Having async and non-async functions in the same trait;<br>
|
113 | 128 | //! > ☑ Default implementations provided by the trait;<br>
|
114 |
| -//! > ☑ Elided lifetimes;<br> |
115 |
| -//! > ☑ Dyn-capable traits.<br> |
| 129 | +//! > ☑ Elided lifetimes.<br> |
116 | 130 | //!
|
117 | 131 | //! <br>
|
118 | 132 | //!
|
|
0 commit comments