Repository: rust
Issue: Minimal support for implicit lifetime bounds on GATs
Labels: T-types,A-GATs

The following Rust code fails to compile:

```rust
// Here we encode the following implicit lifetime bounds:
// - `Long` must live for at least as long as the 'long lifetime.
// - `Self` must live for at least as long as the 'short lifetime.
// - The 'long lifetime must outlive the 'short lifetime,
//   which in turn implies that `Long` must outlive `Self`.
pub trait ImplicitLifetimeBounds<
    'long,
    'short,
    Long: ?Sized,
    _Witnesses = (&'short Self, &'short &'long Long),
> {}

impl<'long, 'short, Long, Short> ImplicitLifetimeBounds<'long, 'short, Long> for Short
where
    Long: ?Sized,
    Short: ?Sized,
{}

pub trait Long<'long>: 'long {
    // when uncommenting the `where` clause it will compile, but the same explicit
    // lifetime bounds are also implied by the `ImplicitLifetimeBounds` trait bound.
    type Short<'short>: ImplicitLifetimeBounds<'long, 'short, Self> /* where 'long: 'short */ ;

    fn use_gat(&self) -> Self::Short<'_>;
}
```

The error message is:

```quote
error: missing required bound on `Short`
  --> examples/implicit2.rs:25:5
   |
25 |     type Short<'short>: ImplicitLifetimeBounds<'long, 'short, Self>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
   |                                                                    |
   |                                                                    help: add the required where clause: `where Self: 'short`
   |
   = note: this bound is currently required to ensure that impls have maximum flexibility
   = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information

error[E0491]: in type `&'short &'long Self`, reference has a longer lifetime than the data it references
  --> examples/implicit2.rs:25:25
   |
25 |     type Short<'short>: ImplicitLifetimeBounds<'long, 'short, Self>;
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: the pointer is valid for the lifetime `'short` as defined here
  --> examples/implicit2.rs:25:16
   |
25 |     type Short<'short>: ImplicitLifetimeBounds<'long, 'short, Self>;
   |                ^^^^^^
note: but the referenced data is only valid for the lifetime `'long` as defined here
  --> examples/implicit2.rs:22:16
   |
22 | pub trait Long<'long>: 'long {
   |                ^^^^^

For more information about this error, try `rustc --explain E0491`.

```

The error message could be clearer if it would suggest to add a `where 'long: 'short` bound on the GAT instead of the suggested `where Self: 'short`. because adding `where Self: 'short` solves the first error, but not the second error. Besides that it would be nice if Rust could support defining implicit lifetime bounds on GATs this way.

The main reason for this second ask, is that this technique could potentially be used to work-around various HRTB issues that occur with GATs that have explicit lifetime bounds (as a kind of "opt-out" for explicit GAT lifetime bounds, but while still providing implicit GAT lifetime bounds). What I'm referring to is that it's currently not (yet) possible to write `for<'a where 'a: 'b>` clauses in HRTBs, but members of the community have pointed out that these can be emulated with implicit lifetime bounds and then still have your cake with HRTBs, too - however, this won't work for many GATs because these always require explicit lifetime bounds for the moment and this somehow blocks the use of implicit lifetimes for this purpose. Here is a post with [more details](https://users.rust-lang.org/t/dynamic-trait-objects-with-gat-lifetimes-using-work-around-on-stable-rust-1-65/82511) as an example of what I mean. The only other existing work-around for HRTBs +  "GATs in their intended form" (i.e. no [super traits](https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats#hrtb-supertrait), [dynamic trait objects](https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats#dyn-trait-as-a-hkt) or [helper traits](https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats#the-better-gats), just GATs as these are currently being stabilized) at the moment is to use a [super-trait](https://sabrinajewson.org/blog/the-better-alternative-to-lifetime-gats#hrtb-supertrait), but imho this is an obstacle for crates in the ecosystem to widely adopt GATs, because having to implement 2 traits instead of 1 trait is not a very ergonomic API design towards end-users. I am aware that there are plans to improve Rust to be able to infer GAT lifetime bounds implicitly and that this is still a significant jump away from stabilization, maybe this proposed approach can be an alternative way to "explicitly" provide "implicit lifetime bounds" for the time being, without the need for chalk in the short term.

I suspect this is probably a very big ask, but wanted to provide this feedback in case it helps somehow for making GATs better. Thanks for all the hard made efforts towards bringing GATs to stable Rust, I am really looking forward to using them!

<details>
<summary>p.s. I am on this Rust version</summary>

```quote
rustc 1.66.0-nightly (0ca356586 2022-10-06)
binary: rustc
commit-hash: 0ca356586fed56002b10920fd21ddf6fb12de797
commit-date: 2022-10-06
host: x86_64-unknown-linux-gnu
release: 1.66.0-nightly
LLVM version: 15.0.2
```

</details>