🧬 Async fn in traits
General goal
trait Foo {
// Currently disallowed:
async fn bar();
}
Concerns
How to name the resulting future
If you wanted to name the future that results from calling bar
(or whatever), you can't.
Also true for functions fn bar() -> impl Trait
.
Requiring Send
on futures
async fn foo() {}
// desugars to
fn foo() -> impl Future<Output = ()> { } // resulting type is Send if it can be
// alternative desugaring we chose not to adopt would require Send
fn foo() -> impl Future + Send { }
If I want to constrain the future I get back from a method, it is difficult to do without a name:
trait Service {
async fn request(&self);
}
fn parallel_service<S: Service>()
where
S::Future: Send,
{
...
}
- Should this be solved at the impl trait layer
- Or should we specialize something for async functions
- Would be nice, if there are many, associated types, to have some shorthand
Example use case: the Service
trait Service {
type Future: Future<Output = Response>;
fn request(&self, ...) -> Self::Future;
}
impl Service for MyService {
type Future = impl Future<Output = Response>;
fn request(&self) -> Self::Future {
async move { .. }
}
}
- Dependent on impl Trait, see lang-team repo
Example use case: capturing lifetimes of arguments
trait MyMethod {
async fn foo(&self);
}
🤔 Frequently Asked Questions
What do people say about this to their friends on twitter?
- (Explain your key points here)