Repository: rust
Issue: Give a better error when HRTB require a function to be valid for 'static references
Labels: A-diagnostics,A-trait-system,A-closures,T-compiler,A-async-await,AsyncAwait-Triaged,D-newcomer-roadblock,D-terse,A-higher-ranked

Given the following code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cace533e183828ffeb2772f434b0611e

```rust
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.
<!-- The following is not always necessary. -->
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
```

<!--
If the problem is not self-explanatory, please provide a rationale for the
change.
-->

<!--
If dramatically different output is caused by small changes, consider also
adding them here.

If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions. The output might also be
different depending on the Edition.
-->


<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"vincenzopalazzo"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->