Skip to content
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

async function traits #14

Open
nrc opened this issue Jul 6, 2022 · 4 comments
Open

async function traits #14

nrc opened this issue Jul 6, 2022 · 4 comments

Comments

@nrc
Copy link
Owner

nrc commented Jul 6, 2022

See async_fn_traits. Essentially traits for functions which return a future. I'm not clear on why there are versions for different numbers of arguments rather than having a generic parameter for the arguments (like the Fn traits). I'm also not clear on how much these traits are just a convenience vs how much the compiler will need to know about their correspondence with the Fn traits to be useful.

@NobodyXu
Copy link

NobodyXu commented Jul 6, 2022

I'm not clear on why there are versions for different numbers of arguments rather than having a generic parameter for the arguments (like the Fn traits).

I suppose that is to work around the lack of variadic generic parameters support in rust.

@SabrinaJewson
Copy link

how much the compiler will need to know about their correspondence with the Fn traits to be useful

The compiler will need to know about them to get type inference with HRTBs to work. Today, this doesn’t compile:

fn example<F: for<'a> AsyncFn1<&'a u32, Output = ()>>(func: F) {}
example(|x| async { dbg!(x); });

and that’s because the Fn bound is only indirectly applied via the AsyncFn1 trait and not in the function. However, we can’t move the Fn bound to the function because then we wouldn’t be able to express what would come after the -> (since its type should be able to vary based on the HRTB).

@joshtriplett
Copy link

Does this get easier if we stabilize async |x| so that we don't just have "function returning a future", we have "async function"?

@SabrinaJewson
Copy link

I mean, potentially. If async |x| were stabilized but it just desugars to |x| async { /* … */ } then obviously not, but I’d imagine it’d be possible to implement it in a “smarter” way, although I’m not a compiler person so I don’t know unfortunately. Another potential solution is to allow -> _ in Fn trait bounds and stabilize FnOnce::Output, so the bound could be written like this:

fn example<F>(func: F)
where
    F: for<'a> Fn(&'a u32) -> _,
    for<'a> <F as Fn(&'a u32) -> _>::Output: Future<Output = ()>,
{}

Or maybe, the compiler could have the example Just Work by propagating the Fn supertrait for type inference correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants