Repository: rust
Issue: HRTB bounds not resolving correctly (take 3, lifetimes on the RHS)
Labels: A-lifetimes,T-compiler,C-bug,S-bug-has-test,fixed-by-next-solver,A-higher-ranked

This is a new version of https://github.com/rust-lang/rust/issues/85636 and https://github.com/rust-lang/rust/issues/89196 . When reporting it I first hit an ICE which got fixed in https://github.com/rust-lang/rust/issues/90638.

The basic idea is that bounds of the form `for<'a> <Type as Trait<'a>>::AssocType: OtherTrait<'a>` don't work. https://github.com/rust-lang/rust/issues/85636, which has since been fixed, is about this same issue without a lifetime on the right side of the bound. This will likely also be a problem for GATs.


The commented out code is not necessary for it to work, but it gives an idea of why such a bound might be necessary.

<details>

```rust
trait Yokeable<'a>: 'static {
    type Output: 'a;
}


trait IsCovariant<'a> {}

struct Yoke<Y: for<'a> Yokeable<'a>> {
    data: Y,
}


// impl<Y: for<'a> Yokeable<'a>> Yoke<Y> {
//     fn project<Y2: for<'a> Yokeable<'a>>(&self, f: for<'a> fn(<Y as Yokeable<'a>>::Output, &'a ()) -> <Y2 as Yokeable<'a>>::Output) -> Yoke<Y2> {
//         unimplemented!()
//     }
// }

fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
    Y: for<'a> Yokeable<'a>,
    for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
    {
    // x.project(|data, _| {
    //     Box::new(data)
    // })
    unimplemented!()
}


impl<'a> Yokeable<'a> for Box<dyn IsCovariant<'static> + 'static> {
    type Output = Box<dyn IsCovariant<'a> + 'a>;
}

// this impl is mostly an example and unnecessary for the pure repro
use std::borrow::*;
impl<'a, T: ToOwned + ?Sized> Yokeable<'a> for Cow<'static, T> {
    type Output = Cow<'a, T>;
}
impl<'a, T: ToOwned + ?Sized> IsCovariant<'a> for Cow<'a, T> {}



fn upcast_yoke(y: Yoke<Cow<'static, str>>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> {
    upcast(y)
}

fn main() {}
```

<details>


([playpen](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=81f4af21c188ad79272d58458986fb3c))

The error shown is:

```
   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `for<'a> <_ as Yokeable<'a>>::Output: IsCovariant<'a>` is not satisfied
  --> src/main.rs:44:5
   |
44 |     upcast(y)
   |     ^^^^^^ the trait `for<'a> IsCovariant<'a>` is not implemented for `<_ as Yokeable<'a>>::Output`
   |
note: required by a bound in `upcast`
  --> src/main.rs:21:42
   |
19 | fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
   |    ------ required by a bound in this
20 |     Y: for<'a> Yokeable<'a>,
21 |     for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
   |                                          ^^^^^^^^^^^^^^^ required by this bound in `upcast`
```


which is incorrect, that bound _is_ satisfied here.


I'm currently working on rustc master (d914f17ca71a33a89b2dc3436fca51b1a091559e) so that I can have the fix for https://github.com/rust-lang/rust/issues/90638, though that fix is not necessary for the commented-out version of my code to work. This should be available on nightly soon.

cc @jackh726 @eddyb