|
1 | 1 | # 🧬 Async fn in traits
|
2 |
| - |
3 |
| -* [Why async fn in traits are hard][wafth] |
4 |
| - |
5 |
| -[wafth]: http://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/ |
6 |
| - |
7 |
| -## General goal |
8 |
| - |
9 |
| -```rust,ignore |
10 |
| -trait Foo { |
11 |
| - // Currently disallowed: |
12 |
| - async fn bar(); |
13 |
| -} |
14 |
| -``` |
15 |
| - |
16 |
| -## Concerns |
17 |
| - |
18 |
| -### How to name the resulting future |
19 |
| - |
20 |
| -If you wanted to name the future that results from calling `bar` (or whatever), you can't. |
21 |
| - |
22 |
| -Also true for functions `fn bar() -> impl Trait`. |
23 |
| - |
24 |
| -### Requiring `Send` on futures |
25 |
| - |
26 |
| -[Relevant thread](https://internals.rust-lang.org/t/how-often-do-you-want-non-send-futures/10360) |
27 |
| - |
28 |
| -```rust,ignore |
29 |
| -async fn foo() {} |
30 |
| -
|
31 |
| -// desugars to |
32 |
| -fn foo() -> impl Future<Output = ()> { } // resulting type is Send if it can be |
33 |
| -
|
34 |
| -// alternative desugaring we chose not to adopt would require Send |
35 |
| -fn foo() -> impl Future + Send { } |
36 |
| -``` |
37 |
| - |
38 |
| -If I want to constrain the future I get back from a method, it is difficult to do without a name: |
39 |
| - |
40 |
| -```rust,ignore |
41 |
| -trait Service { |
42 |
| - async fn request(&self); |
43 |
| -} |
44 |
| -
|
45 |
| -fn parallel_service<S: Service>() |
46 |
| -where |
47 |
| - S::Future: Send, |
48 |
| -{ |
49 |
| - ... |
50 |
| -} |
51 |
| -``` |
52 |
| - |
53 |
| -* Should this be solved at the impl trait layer |
54 |
| -* Or should we specialize something for async functions |
55 |
| -* Would be nice, if there are many, associated types, to have some shorthand |
56 |
| - |
57 |
| -## Example use case: the Service |
58 |
| - |
59 |
| -```rust,ignore |
60 |
| -trait Service { |
61 |
| - type Future: Future<Output = Response>; |
62 |
| -
|
63 |
| - fn request(&self, ...) -> Self::Future; |
64 |
| -} |
65 |
| -
|
66 |
| -impl Service for MyService { |
67 |
| - type Future = impl Future<Output = Response>; |
68 |
| -
|
69 |
| - fn request(&self) -> Self::Future { |
70 |
| - async move { .. } |
71 |
| - } |
72 |
| -} |
73 |
| -``` |
74 |
| - |
75 |
| -* Dependent on impl Trait, see lang-team repo |
76 |
| - |
77 |
| -## Example use case: capturing lifetimes of arguments |
78 |
| - |
79 |
| -```rust,ignore |
80 |
| -trait MyMethod { |
81 |
| - async fn foo(&self); |
82 |
| -} |
83 |
| -``` |
84 |
| - |
85 |
| -## 🤔 Frequently Asked Questions |
86 |
| - |
87 |
| -### **What do people say about this to their friends on twitter?** |
88 |
| -* (Explain your key points here) |
0 commit comments