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 fn unmet lifetime constraints produce confusing diagnostics #66168

Open
s97712 opened this issue Nov 6, 2019 · 2 comments

Comments

@s97712
Copy link

@s97712 s97712 commented Nov 6, 2019

use std::future::Future;

struct Foo<'a> {
  pub value: &'a str
}

fn mode_1(_b: Foo<'_>) -> impl Future<Output=()> {
  async {}
}

async fn mode_2(_b: Foo<'_>) {
}


fn test<F, Fut>(_f: F ) 
  where
    Fut: Future<Output=()>,
    F: FnOnce(Foo<'_>) -> Fut,
{
    
}


fn main() {

    // here can compiled
    test(mode_1);
    
    // here can't compiled
    test(mode_2);
}
   Compiling playground v0.0.1 (/playground)
error[E0271]: type mismatch resolving `for<'r> <for<'_> fn(Foo<'_>) -> impl std::future::Future {mode_2} as std::ops::FnOnce<(Foo<'r>,)>>::Output == _`
  --> src/main.rs:29:5
   |
14 | fn test<F, Fut>(_f: F ) 
   |    ----
...
17 |     F: FnOnce(Foo<'_>) -> Fut,
   |                           --- required by this bound in `test`
...
29 |     test(mode_2);
   |     ^^^^ expected bound lifetime parameter, found concrete lifetime

error: aborting due to previous error

For more information about this error, try `rustc --explain E0271`.

rust playground

@estebank

This comment has been minimized.

Copy link
Contributor

@estebank estebank commented Nov 7, 2019

Note that you can write code that will compile for this, it is just not obvious (note the added explicit lifetime 'r):

fn test<'r, F, Fut>(_f: F) 
  where
    Fut: Future<Output=()> + 'r,
    F: FnOnce(Foo<'r>) -> Fut,

The reason one works and the other one doesn't is because they are not equivalent. mode_2 gets desugared to

fn mode_2(_b: Foo<'_>) -> impl Future<Output=()> + '_ { // note the relaxing of the lifetime constraint to the return type
  async {}
}

which also doesn't compile unless you add a lifetime to test.

I believe there are already quite a few A-async-await tickets about the default behavior of lifetimes needing some work.

@estebank estebank changed the title async fn bug async fn unmet lifetime constraints produce confusing diagnostics Nov 7, 2019
@s97712

This comment was marked as resolved.

Copy link
Author

@s97712 s97712 commented Nov 17, 2019

I try to use async fn as callback:

fn test<F, Fut>(_f: F) 
  where
    Fut: Future<Output=()>,
    F: for<'r> FnOnce(Foo<'r>) -> Fut +'r,

but get a error:

17 |     F: for<'r> FnOnce(Foo<'r>) -> Fut + 'r,
   |                                         ^^ undeclared lifetime

Is there a solution to this problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.