Repository: rust
Issue: impl Trait does not capture lifetime of generic argument
Labels: A-type-system,A-lifetimes,T-lang,A-impl-trait,T-types

According to [RFC 1951](https://github.com/rust-lang/rfcs/blob/master/text/1951-expand-impl-trait.md), `impl Trait` in return position should capture the lifetime of any associated generic parameters. However, in this code, that logic appears not to work ([playground](https://play.rust-lang.org/?version=beta&mode=debug&edition=2018&gist=62d220b0533fcb9530ee5f2c75ac31c4)):

```rust
use std::future::Future;
use std::pin::Pin;

struct A;

impl A {
    fn a<T>(&self, t: T) -> impl Future<Output = ()> {
        let _ = t;
        async {}
    }
}

struct B(A);

impl B {
    fn works<'a, T: 'a>(
        self,
        t: T,
    ) -> impl Future<Output = (Self, impl Future<Output = ()> + 'a)> + 'a {
        async move {
            let f = Pin::from(Box::new(self.0.a(t)) as Box<dyn Future<Output = _>>);
            (self, f)
        }
    }

    fn doesnt_work<T>(self, t: T) -> impl Future<Output = (Self, impl Future<Output = ()>)> {
        async move {
            let f = Pin::from(Box::new(self.0.a(t)) as Box<dyn Future<Output = _>>);
            (self, f)
        }
    }
}
```

Specifically, the compiler gives two _almost_ identical errors for the `doesnt_work` method:
```
error[E0310]: the parameter type `T` may not live long enough
  --> src/lib.rs:28:31
   |
26 |     fn doesnt_work<T>(self, t: T) -> impl Future<Output = (Self, impl Future<Output = ()>)> {
   |                    - help: consider adding an explicit lifetime bound `T: 'static`...
27 |         async move {
28 |             let f = Pin::from(Box::new(self.0.a(t)) as Box<dyn Future<Output = _>>);
   |                               ^^^^^^^^^^^^^^^^^^^^^
   |
note: ...so that the type `impl std::future::Future` will meet its required lifetime bounds
  --> src/lib.rs:28:31
   |
28 |             let f = Pin::from(Box::new(self.0.a(t)) as Box<dyn Future<Output = _>>);
   |                               ^^^^^^^^^^^^^^^^^^^^^
```
and
```
error[E0310]: the parameter type `T` may not live long enough
  --> src/lib.rs:28:31
   |
26 |     fn doesnt_work<T>(self, t: T) -> impl Future<Output = (Self, impl Future<Output = ()>)> {
   |                    - help: consider adding an explicit lifetime bound `T: 'static`...
27 |         async move {
28 |             let f = Pin::from(Box::new(self.0.a(t)) as Box<dyn Future<Output = _>>);
   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: ...so that it can be closed over into an object
  --> src/lib.rs:28:31
   |
28 |             let f = Pin::from(Box::new(self.0.a(t)) as Box<dyn Future<Output = _>>);
   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

I was (perhaps mistakenly) under the impression that the semantics of `impl Trait` in return position should be as the explicit lifetimes on the `works` method indicate, but that doesn't seem to be the case? When the lifetimes are explicitly annotated, as in the `works` method, the method compiles just fine.