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

Borrowing from arguments with higher order async functions #66198

madmaxio opened this issue Nov 7, 2019 · 3 comments

Borrowing from arguments with higher order async functions #66198

madmaxio opened this issue Nov 7, 2019 · 3 comments


Copy link

@madmaxio madmaxio commented Nov 7, 2019

Hi, just wanted to ask if borrow with higher order async fns (from there arguments) is not correct never at all, or there might be some solutions in the future. Please check the example.

use std::future::Future;

async fn f(data: &Vec<String>) {

async fn start<Fut>(prm: fn(&Vec<String>) -> Fut) 
    Fut: Future<Output = ()>
    let data = vec![];

fn main() {



   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/
16 |     start(f);
   |           ^ expected concrete lifetime, found bound lifetime parameter
   = note: expected type `for<'r> fn(&'r std::vec::Vec<std::string::String>) -> _`
              found type `for<'_> fn(&std::vec::Vec<std::string::String>) -> impl std::future::Future {f}`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Copy link

@cramertj cramertj commented Nov 7, 2019

start only accepts a single type Fut, yet the type returned from async fn f is dependent upon the lifetime of the data parameter.

Copy link

@nikomatsakis nikomatsakis commented Nov 12, 2019

This example is indeed behaving as expected. The problem here, @madmaxio, is maybe more clear if we expand the signature:

async fn start<Fut>(prm: for<'a> fn(&'a Vec<String>) -> Fut) 

Here the problem is that the argument lifetime ('a) is not in scope for the type Fut, so it can't be part of that type. You could refactor this to:

async fn start<'a, Fut>(prm: fn(&'a Vec<String>) -> Fut) 

but that might not work well with the overall design. I'm going to close the issue, in any case, as "working as intended", and suggest you take the example to to try and get more feedback on how best to fix it. :)

Copy link

@madmaxio madmaxio commented Nov 12, 2019

Thank you guys for the reply. I'm passing parameter by move now. Makes sense borrowing is not allowed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants