dtolnay / dtolnay/async-trait

Issue with reference lifetimes in closures

Open
#257 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
2.2k
Forks
101
PR merge metrics
No merged PRs in 30d

Description

On latest `async-trait` (0.1.77) this code doesn't compile:

```rs
struct Foo;

#[async_trait::async_trait]
trait Bar {
async fn foo(&self, call: &(dyn (Fn(&String) -> bool) + Sync));
}

#[async_trait::async_trait]
impl Bar for Foo {
async fn foo(&self, call: &(dyn (Fn(&String) -> bool) + Sync)) {
let thing = "a".to_string();
call(&thing);
}
}

fn main() {
Foo::foo(&Foo, &|a| a == "a");
}
```

This expands to:

```rs
fn foo<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
call: &'life1 (dyn (Fn(&'life2 String) -> bool) + Sync),
) -> ::core::pin::Pin<
Box<
dyn ::core::future::Future + ::core::marker::Send + 'async_trait,
>,
>
where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait;
```

And gives the compiler error:

```
error[E0597]: `thing` does not live long enough
--> src/main.rs:12:14
|
10 | async fn foo(&self, call: &(dyn (Fn(&String) -> bool) + Sync)) {
| ---- lifetime `'1` appears in the type of `call`
11 | let thing = "a".to_string();
| ----- binding `thing` declared here
12 | call(&thing);
| -----^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `thing` is borrowed for `'1`
13 | }
| - `thing` dropped here while still borrowed
```

Manually removing `'life2` makes the code compile.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the example in src/main.rs and inspecting the async-trait expansion shown in the issue, focusing on the generated 'life2 constraint. Done means the example compiles without manually removing that lifetime and the behavior is covered by an appropriate regression case.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.