Repository: rust
Issue: RPITIT with Send trait marker breaks borrow checker
Labels: A-borrow-checker,C-bug,F-return_position_impl_trait_in_trait

<!--
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.
-->

I tried this code:

```rust
#![feature(return_position_impl_trait_in_trait)]
use std::future::Future;

pub trait Foo: Sync {
    fn run<'a, 'b: 'a, T: Sync>(&'a self, _: &'b T) -> impl Future<Output = ()> + 'a + Send; // doesn't compile
    // fn run<'a, 'b, T: Sync>(&'a self, _: &'b T) -> impl Future<Output = ()> + 'a + Send; // compiles
}

pub trait FooExt: Foo {
    fn run_via<'a, 'b: 'a, T: Sync>(&'a self, t: &'b T) -> impl Future<Output = ()> + 'a + Send {
        async move {
            // asks for an unspecified lifetime to outlive itself? weird diagnostics
            self.run(t).await;
        }
    }
}
```

I expected to see this happen: successful compilation

Instead, this happened: an outlives lifetime error with very bad diagnostics

```
error: lifetime bound not satisfied
  --> src/lib.rs:12:9
   |
12 | /         async move {
13 | |             // asks for an unspecified lifetime to outlive itself? weird diagnostics
14 | |             self.run(t).await;
15 | |         }
   | |_________^
   |
note: the lifetime defined here...
  --> src/lib.rs:14:18
   |
14 |             self.run(t).await;
   |                  ^^^
note: ...must outlive the lifetime defined here
  --> src/lib.rs:14:18
   |
14 |             self.run(t).await;
   |                  ^^^
   = note: this is a known limitation that will be removed in the future ([see issue #100013 <https://github.com/rust-lang/rust/issues/100013>](https://github.com/rust-lang/rust/issues/100013) for more information)
```

Then I tried this code:
```rust
pub trait Foo: Sync {
    fn run<'a, 'b: 'a, T: Sync>(&'a self, _: &'b T) -> impl Future<Output = ()> + 'a;
}

pub trait FooExt: Foo {
    fn run_via<'a, 'b: 'a, T: Sync>(&'a self, t: &'b T) -> impl Future<Output = ()> + 'a {
        async move {
            self.run(t).await; // compiles now!
        }
    }
}
```

And the code compiled! Seems like `Send` bound on the return impl trait type in `run` function breaks borrow checker in some way, or possibly breaks inner definition of the anonymous impl type since the following code with a trait object *works*.

```rust
#![feature(return_position_impl_trait_in_trait)]
use std::{pin::Pin, future::Future};

pub trait Foo: Sync {
    fn run<'a, 'b: 'a, T: Sync>(&'a self, _: &'b T) -> Pin<Box<dyn Future<Output = ()> + 'a + Send>>;
}

pub trait FooExt: Foo {
    // this function still has a RPITIT
    fn run_via<'a, 'b: 'a, T: Sync>(&'a self, t: &'b T) -> impl Future<Output = ()> + 'a + Send {
        async move {
            // works!
            self.run(t).await;
        }
    }
}
```

### `-Ztrait-solver=next` and polonius

First code snippet leads to an ICE when using `-Ztrait-solver=next`, I am not sure whether it's worth filing an ICE report right now because this is a bug in the default solver. As for polonius, it doesn't change anything.

### 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.71.0-nightly (dbba59457 2023-05-01)
binary: rustc
commit-hash: dbba594575ce75b1b57ccb1e4223b9909a28b1b8
commit-date: 2023-05-01
host: x86_64-unknown-linux-gnu
release: 1.71.0-nightly
LLVM version: 16.0.2
```

</p>
</details>