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

s97712 opened this issue Nov 6, 2019 · 2 comments


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 ) 
    Fut: Future<Output=()>,
    F: FnOnce(Foo<'_>) -> Fut,

fn main() {

    // here can compiled
    // here can't compiled
   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/
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


This comment has been minimized.

Copy link

@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) 
    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

This comment was marked as resolved.

Copy link

@s97712 s97712 commented Nov 17, 2019

I try to use async fn as callback:

fn test<F, Fut>(_f: F) 
    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
None yet
4 participants
You can’t perform that action at this time.