Open
Description
Compiling the following code:
trait Foo: Sync + Send {
type A<'a>: Bar + 'a
where
Self: 'a;
fn get<'a>(&'a self) -> Self::A<'a>;
}
trait Bar: Sync + Send {}
fn do_something<'a, T: Foo + 'a>(obj: &'a T) -> impl Future<Output = ()> + Send + 'a {
async move {
let x = obj.get();
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
drop(x)
}
}
I would have expected it to compile without errors. Instead it reports
Compiling playground v0.0.1 (/playground)
error: `T` does not live long enough
--> src/lib.rs:12:5
|
12 | / async move {
13 | | let x = obj.get();
14 | | tokio::time::sleep(std::time::Duration::from_secs(1)).await;
15 | | drop(x)
16 | | }
| |_____^
error: could not compile `playground` (lib) due to 1 previous error
Removing either the Send bound on the future returned by do_something, or removing the sleep call, both make the function compile succesfully.
Should anyone else run into this, the following workaround is accepted as by the compiler:
trait Foo: Sync + Send {
type A<'a>: Bar + 'a
where
Self: 'a;
fn get<'a>(&'a self) -> Self::A<'a>;
}
trait Bar: Sync + Send {}
fn do_something<'a, T: Foo + 'a>(obj: &'a T) -> impl Future<Output = ()> + Send + 'a {
fn do_inner<'b, U: Bar + 'b>(x: U) -> impl Future<Output = ()> + Send + 'b {
async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
drop(x)
}
}
async move {
let x = obj.get();
do_inner(x).await
}
}
This may be related to #92096, but the code and error are different enough that I am not entirely sure about that.
Meta
This occured on a nightly compiler version from rust playground, and on the latest stable (1.88.0). Rust playground reported the following version info for nightly:
(2025-07-03 da58c051315268a197ce)