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

Closed
madmaxio opened this issue Nov 7, 2019 · 3 comments
Closed

Borrowing from arguments with higher order async functions #66198

madmaxio opened this issue Nov 7, 2019 · 3 comments
Labels
A-async-await Area: Async & Await A-lifetimes Area: lifetime related T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@madmaxio
Copy link

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) 
where
    Fut: Future<Output = ()>
{
    let data = vec![];
    prm(&data).await;
}

fn main() {
    start(f);
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/main.rs:16:11
   |
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.

@estebank estebank added A-async-await Area: Async & Await A-lifetimes Area: lifetime related T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Nov 7, 2019
@cramertj
Copy link
Member

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.

@nikomatsakis
Copy link
Contributor

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 users.rust-lang.org to try and get more feedback on how best to fix it. :)

@madmaxio
Copy link
Author

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
Labels
A-async-await Area: Async & Await A-lifetimes Area: lifetime related T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants