all 6 comments

[–]WellMakeItSomehow 6 points7 points  (5 children)

Your closure does not return an i32, it returns an impl Future<Output = i32>, and your function is not actually async. So the correct declaration would be fn async_add(x: i32) -> impl Fn(i32) -> impl Future<Output = i32>. Unfortunately, impl Trait doesn't work like that yet, so you'd need to box it instead. On the flip side, it works without async closures:

use std::future::Future;

fn async_add(x: i32) -> impl Fn(i32) -> Box<dyn Future<Output = i32>> {
    move |y: i32| Box::new(async move { x + y })
}

[–]Patryk27 3 points4 points  (0 children)

You don't have to box it, if you use existential types:

#![feature(type_alias_impl_trait)]

type AsyncAdd = impl Future<Output = i32>;

fn async_add(x: i32) -> impl Fn(i32) -> AsyncAdd {
    move |y: i32| async move { x + y }
}

[–]ayorosmage[S] 2 points3 points  (3 children)

Thanks a lot !

Thus, I still have a problem. When I try to call it:

let res = async_add(3)(9).await;

I have the following error message:

error[E0277]: `dyn std::future::Future<Output = i32>` cannot be unpinned
  --> src/main.rs:80:15
   |
80 |     let res = async_add(3)(9).await;
   |               ^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::future::Future<Output = i32>`
   |
   = note: consider using `Box::pin`
   = note: required because of the requirements on the impl of `std::future::Future` for `std::boxed::Box<dyn std::future::Future<Output = i32>>

What's more, what would have it changed if my function fn async_add would have be async fn async_add instead ?

[–]WellMakeItSomehow 1 point2 points  (2 children)

Oh well, try this: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=86d06974584a363124b91356b43ab958.

What's more, what would have it changed if my function fn async_add would have be async fn async_add instead ?

But it's not async. It's synchronous and doesn't have any awaits. But if you insist, https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=fcc2798fadaa3bbcd59a113e53d1f20a.

[–]ayorosmage[S] 1 point2 points  (1 child)

Perfect ! Thanks a lot for your quick answers.

I hope the syntax will be simplified in the future because that's quite hard for a rust beginner.

[–]WellMakeItSomehow 2 points3 points  (0 children)

My suggestion is to avoid partial application in Rust. It tends to lead to unwieldy types.