Skip to content

Higher ranked lifetime error when checking auto traits of async functions containing calls to async closures which capture a local #134997

Open
@jdonszelmann

Description

@jdonszelmann

I tried this code:

#![feature(async_fn_traits)]

use std::ops::AsyncFn;

// this function is important, inlining it breaks the poc.
// We also tried replacing it with `identity` but the fact that this is an
// async function calling the closure inside is also relevant.
async fn do_not_inline(f: impl AsyncFn()) {
    f().await;
}

fn foo() -> impl Send {
    async move {
        // just replacing this with unit, leaves the error with `Send` but fixes the
        // "higher-ranked lifetime error"
        let s = &();

        do_not_inline(async || {
            &s;
        })
        .await;
    }
}

I expected to see this happen: compilation succeeds
Instead, this happened:

error: implementation of `Send` is not general enough
  --> src/lib.rs:13:5
   |
13 | /     async move {
14 | |         // just replacing this with unit, leaves the error with `Send` but fixes the
15 | |         // "higher-ranked lifetime error"
16 | |         let s = &();
...  |
21 | |         .await;
22 | |     }
   | |_____^ implementation of `Send` is not general enough
   |
   = note: `Send` would have to be implemented for the type `&'0 &()`, for any lifetime `'0`...
   = note: ...but `Send` is actually implemented for the type `&'1 &()`, for some specific lifetime `'1`

error: higher-ranked lifetime error
  --> src/lib.rs:13:5
   |
13 | /     async move {
14 | |         // just replacing this with unit, leaves the error with `Send` but fixes the
15 | |         // "higher-ranked lifetime error"
16 | |         let s = &();
...  |
21 | |         .await;
22 | |     }
   | |_____^

error: could not compile `noteslsp` (lib) due to 2 previous errors

try it here: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=ab71ed9cfa6f91320c7a24fe7f2bdca9

note, we got here through a bigger example, the impl Send used to come from the async_trait library where it produced Pin<Box<dyn Future<Output=()> + Send>> but most of that was not relevant for the mcve.

Meta

rustc --version --verbose:

rustc 1.85.0-nightly (d117b7f21 2024-12-31)
binary: rustc
commit-hash: d117b7f211835282b3b177dc64245fff0327c04c
commit-date: 2024-12-31
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6

cc: @compiler-errors

@rustbot label +F-async_closure +T-compiler +A-auto-traits

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-closures`async || {}`A-auto-traitsArea: auto traits (e.g., `auto trait Send {}`)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions