|
213 | 213 | //! async fn test(elided: Elided<'_>) {}
|
214 | 214 | //! }
|
215 | 215 | //! ```
|
216 |
| -//! |
217 |
| -//! <br><br> |
218 |
| -//! |
219 |
| -//! # Dyn traits |
220 |
| -//! |
221 |
| -//! Traits with async methods can be used as trait objects as long as they meet |
222 |
| -//! the usual requirements for dyn -- no methods with type parameters, no self |
223 |
| -//! by value, no associated types, etc. |
224 |
| -//! |
225 |
| -//! ``` |
226 |
| -//! # use async_trait::async_trait; |
227 |
| -//! # |
228 |
| -//! #[async_trait] |
229 |
| -//! pub trait ObjectSafe { |
230 |
| -//! async fn f(&self); |
231 |
| -//! async fn g(&mut self); |
232 |
| -//! } |
233 |
| -//! |
234 |
| -//! # const IGNORE: &str = stringify! { |
235 |
| -//! impl ObjectSafe for MyType {...} |
236 |
| -//! |
237 |
| -//! let value: MyType = ...; |
238 |
| -//! # }; |
239 |
| -//! # |
240 |
| -//! # struct MyType; |
241 |
| -//! # |
242 |
| -//! # #[async_trait] |
243 |
| -//! # impl ObjectSafe for MyType { |
244 |
| -//! # async fn f(&self) {} |
245 |
| -//! # async fn g(&mut self) {} |
246 |
| -//! # } |
247 |
| -//! # |
248 |
| -//! # let value: MyType = MyType; |
249 |
| -//! let object = &value as &dyn ObjectSafe; // make trait object |
250 |
| -//! ``` |
251 |
| -//! |
252 |
| -//! The one wrinkle is in traits that provide default implementations of async |
253 |
| -//! methods. In order for the default implementation to produce a future that is |
254 |
| -//! Send, the async_trait macro must emit a bound of `Self: Sync` on trait |
255 |
| -//! methods that take `&self` and a bound `Self: Send` on trait methods that |
256 |
| -//! take `&mut self`. An example of the former is visible in the expanded code |
257 |
| -//! in the explanation section above. |
258 |
| -//! |
259 |
| -//! If you make a trait with async methods that have default implementations, |
260 |
| -//! everything will work except that the trait cannot be used as a trait object. |
261 |
| -//! Creating a value of type `&dyn Trait` will produce an error that looks like |
262 |
| -//! this: |
263 |
| -//! |
264 |
| -//! ```text |
265 |
| -//! error: the trait `Test` cannot be made into an object |
266 |
| -//! --> src/main.rs:8:5 |
267 |
| -//! | |
268 |
| -//! 8 | async fn cannot_dyn(&self) {} |
269 |
| -//! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
270 |
| -//! ``` |
271 |
| -//! |
272 |
| -//! For traits that need to be object safe and need to have default |
273 |
| -//! implementations for some async methods, there are two resolutions. Either |
274 |
| -//! you can add Send and/or Sync as supertraits (Send if there are `&mut self` |
275 |
| -//! methods with default implementations, Sync if there are `&self` methods with |
276 |
| -//! default implementations) to constrain all implementors of the trait such that |
277 |
| -//! the default implementations are applicable to them: |
278 |
| -//! |
279 |
| -//! ``` |
280 |
| -//! # use async_trait::async_trait; |
281 |
| -//! # |
282 |
| -//! #[async_trait] |
283 |
| -//! pub trait ObjectSafe: Sync { // added supertrait |
284 |
| -//! async fn can_dyn(&self) {} |
285 |
| -//! } |
286 |
| -//! # |
287 |
| -//! # struct MyType; |
288 |
| -//! # |
289 |
| -//! # #[async_trait] |
290 |
| -//! # impl ObjectSafe for MyType {} |
291 |
| -//! # |
292 |
| -//! # let value = MyType; |
293 |
| -//! |
294 |
| -//! let object = &value as &dyn ObjectSafe; |
295 |
| -//! ``` |
296 |
| -//! |
297 |
| -//! or you can strike the problematic methods from your trait object by |
298 |
| -//! bounding them with `Self: Sized`: |
299 |
| -//! |
300 |
| -//! ``` |
301 |
| -//! # use async_trait::async_trait; |
302 |
| -//! # |
303 |
| -//! #[async_trait] |
304 |
| -//! pub trait ObjectSafe { |
305 |
| -//! async fn cannot_dyn(&self) where Self: Sized {} |
306 |
| -//! |
307 |
| -//! // presumably other methods |
308 |
| -//! } |
309 |
| -//! # |
310 |
| -//! # struct MyType; |
311 |
| -//! # |
312 |
| -//! # #[async_trait] |
313 |
| -//! # impl ObjectSafe for MyType {} |
314 |
| -//! # |
315 |
| -//! # let value = MyType; |
316 |
| -//! |
317 |
| -//! let object = &value as &dyn ObjectSafe; |
318 |
| -//! ``` |
319 | 216 |
|
320 | 217 | #![doc(html_root_url = "https://docs.rs/async-trait/0.1.85")]
|
321 | 218 | #![allow(
|
|
0 commit comments