Repository: rust
Issue: Unexpected "the parameter type X may not live long enough" error in asynchronous functions
Labels: A-lifetimes,A-trait-system,T-compiler,A-async-await,AsyncAwait-Triaged,WG-async,T-types,F-impl_trait_in_assoc_type,A-GATs

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

When a `Future` is wrapped in an `async` block or an `async` function, some of its traits are lost, e.g., Send, thus causing various issues.

I tried this code:

```rust
#![feature(impl_trait_in_assoc_type)]

use std::future::Future;

pub trait Get: Send + Sync {
    type Ret<'a>: Future<Output = usize> + Send + 'a
    where
        Self: 'a;
    fn get<'a>(&'a self) -> Self::Ret<'a>
    where
        Self: 'a;
}

impl Get for usize {
    type Ret<'a> = impl Future<Output = usize> + Send + 'a
    where
        Self: 'a;

    fn get<'a>(&'a self) -> Self::Ret<'a>
    where
        Self: 'a,
    {
        async move { *self }
    }
}

fn is_send<R, F: Future<Output = R> + Send>(_f: &F) -> bool {
    true
}

async fn wrap<G: Get>(g: &G) -> usize {
    let fut = g.get();
    assert!(is_send(&fut));
    fut.await
}

async fn wrap_wrap<G: Get>(g: &G) -> usize {
    let fut = wrap(g);
    assert!(is_send(&fut)); //~ ERROR the parameter type `G` may not live long enough
    fut.await
}
```

I expected to see no compiler errors: the returned `Future` from `async fn wrap` should be `Send`, because `g.get()` is `Send` and `async fn wrap` only wraps the code in an asynchronous code block.

Instead, this happened: the returned `Future` from `async fn wrap` is not anymore `Send`. Note that the error manifests differently if another lifetime bounds are involved in the trait - `lifetime bound not satisfied` when asserting `is_send(&fut)`. It's even strange to see `lifetime bounds` or `may not live long enough` errors when checking the `Send` bound.

### Meta
<!--
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.
-->

`rustc --version --verbose`:
```
rustc 1.59.0 (9d1b2106e 2022-02-23)
binary: rustc
commit-hash: 9d1b2106e23b1abd32fce1f17267604a5102f57a
commit-date: 2022-02-23
host: aarch64-apple-darwin
release: 1.59.0
LLVM version: 13.0.0
```

<!--
Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in your
environment. E.g. `RUST_BACKTRACE=1 cargo build`.
-->
<details><summary>Error</summary>
<p>

```
error[E0311]: the parameter type `G` may not live long enough
   --> tests/test.rs:687:17
    |
684 |     async fn wrap_wrap<G: Get>(g: &G) -> usize {
    |                        -- help: consider adding an explicit lifetime bound...: `G: 'a +`
...
687 |         assert!(is_send(&fut));
    |                 ^^^^^^^ ...so that the type `G` will meet its required lifetime bounds...
    |
note: ...that is required by this bound
   --> tests/test.rs:674:43
    |
674 |     fn is_send<R, F: Future<Output = R> + Send>(_f: &F) -> bool {
    |                                           ^^^^

error: could not compile `async-trait` due to previous error
```

</p>
</details>