Open
Description
Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cace533e183828ffeb2772f434b0611e
use std::future::Future;
use std::pin::Pin;
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
#[derive(Default)]
struct B(bool);
#[derive(Default)]
struct A {
a: bool,
b: B,
}
impl A {
fn b_mut(&mut self) -> &mut B {
&mut self.b
}
}
async fn entrypoint() {
let mut a = A::default();
let list = vec![];
foo(&mut a, |b| Box::pin(baz(b, &list))).await;
}
async fn foo<'a, F>(a: &'a mut A, f: F)
where
F: for<'b> FnOnce(&'b mut B) -> BoxFuture<'b, ()>,
{
f(a.b_mut()).await;
}
async fn baz(b: &mut B, _: &[u8]) {
b.0 = !b.0;
}
The current output is:
error[E0597]: `list` does not live long enough
--> src/lib.rs:25:38
|
25 | foo(&mut a, |b| Box::pin(baz(b, &list))).await;
| --- -----------------^^^^--
| | | |
| | | borrowed value does not live long enough
| | returning this value requires that `list` is borrowed for `'static`
| value captured here
26 | }
| - `list` dropped here while still borrowed
This is correct, but hard to understand.
Ideally the output should look like:
error[E0597]: `list` does not live long enough
--> src/lib.rs:25:38
|
25 | foo(&mut a, |b| Box::pin(baz(b, &list))).await;
| --- -----------------^^^^--
| | | |
| | | borrowed value does not live long enough
| | returning this value requires that `list` is borrowed for `'static`
| value captured here
26 | }
| - `list` dropped here while still borrowed
|
| = note: the lifetime cannot be shortened from `'static` to `'b` because closures are contravariant: https://doc.rust-lang.org/nomicon/subtyping.html#variance
|
| = note: the closure passed to `foo` must be valid for any lifetime, including the `'static` lifetime
28 | async fn foo<'a, F>(a: &'a mut A, f: F)
| ^^^^
| F: for<'b> FnOnce(&'b mut B) -> BoxFuture<'b, ()>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| due to the bound here
Metadata
Metadata
Assignees
Labels
Area: Async & AwaitArea: Closures (`|…| { … }`)Area: Messages for errors, warnings, and lintsArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)Area: Trait systemAsync-await issues that have been triaged during a working group meeting.Diagnostics: Confusing error or lint; hard to understand for new users.Diagnostics: An error or lint that doesn't give enough information about the problem at hand.Relevant to the compiler team, which will review and decide on the PR/issue.