-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support async fn
in trait methods (async/await follow-up)
#2739
Comments
I believe that this is blocked on GATs?
… On Aug 5, 2019, at 10:57 AM, Ben Striegel ***@***.***> wrote:
As noted by the author of the async/await RFC during its discussion:
If the answer is just "this can't be used on trait methods", that removes a lot of the utility of this feature, especially for libraries.
This RFC does not propose enabling async trait methods. I agree that trait methods are an extremely valuable use case for async notation, and from my perspective it is the absolute highest priority extension after this initial MVP proposal (in contrast to things like async generators).
#2394 (comment)
Now that the async/await MVP is tentatively approaching stabilization, this is the next logical feature that users are going to start asking about. Discussion of how to support this feature is currently fragmented across various other async/await issues threads, so I have opened this issue in order to centralize discussion (and hopefully to have someone in-the-know summarize the current obstacles and plans).
cc @withoutboats
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
After looking around I believe it is blocked on not only generic associated types but also existentials in traits, both of which have accepted RFCs (#1598 and #2071). The current metabug encompassing this work appears to be rust-lang/rust#63066 , although I'm unclear what subset of those features are required for async trait functions specifically (we may very well need a full RFC to determine that). |
The next step after existential associated types in traits might be to support i.e. once GATs and "impl Trait in type aliases" are implemented it should be possible to do this: trait Foo {
type Bar<'a>: Future<Output = ()> + 'a;
fn bar(&self) -> Self::Bar<'_>;
}
impl Foo for () {
type Bar<'a> = impl Future<Output = ()> + 'a;
fn bar(&self) -> Self::Bar<'_> {
async move {
println!("{:?}", self);
}
}
} this could then be simplified to something like trait Foo {
fn bar(&self) -> impl Future<Output = ()> + '_;
}
impl Foo for () {
fn bar(&self) -> impl Future<Output = ()> + '_ {
async move {
println!("{:?}", self);
}
}
} and finally that should be fundamentally equivalent to trait Foo {
async fn bar(&self);
}
impl Foo for () {
async fn bar(&self) {
println!("{:?}", self);
}
} The biggest issues I see with the latter two sugars are how to deal with an unnameable associated type, e.g. first question I thought of is how do you use it as a trait object like you can with the first ( |
If the question is how to refer to a type that's been implicitly generated in such a way, perhaps that means having something like (Alternatively perhaps we could paper over it somehow with something like |
If you used the sugared notation for the trait would it be compatible with a non-async function returning a custom future type. For example trait Foo {
async fn bar(&self);
}
impl Foo for () {
fn bar(&self) -> impl Future<Output = ()> + '_ {
MyFuture{...}
}
} |
You can always write an async fn that simply trait Foo {
async fn bar(&self);
}
impl Foo for () {
async fn bar(&self) {
MyFuture{...}.await
}
} There is a reason to want a non-async fn in the implementation though (whether you're returning a custom future type or not), sometimes you want to do some minimal synchronous setup before returning impl Foo for () {
fn bar(&self) -> impl Future<Output = ()> + '_ {
// sync part of function
async {
// async part of function
}
}
} Because the trait definition already constrains the lifetimes involved this is mostly useful as an optimization, you may be able to reduce the size of the futures state by pre-calculating some data from the arguments. |
Niko has a very good blog post on this topic: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/ |
I think this is covered by rust-lang/rust#91611 , so can be closed? |
As noted by the author of the async/await RFC during its discussion:
#2394 (comment)
Now that the async/await MVP is tentatively approaching stabilization, this is the next logical feature that users are going to start asking about. Discussion of how to support this feature is currently fragmented across various other async/await issues threads, so I have opened this issue in order to centralize discussion (and hopefully to have someone in-the-know summarize the current obstacles and plans).
cc @withoutboats
The text was updated successfully, but these errors were encountered: