Repository: rust
Issue: Lifetimes block the nice "reached the recursion limit while instantiating" error and get an evaluation overflow instead
Labels: A-diagnostics,A-trait-system,T-compiler

Given the following code: [[playground]](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=85b7297adf55fd3983851375ed079c50)

```rust
#![recursion_limit = "64"] // be nice to the playground

trait VisitMany<'a> { type VisitOneDelegate: VisitOne<'a>; }
trait VisitOne<'a> { type VisitManyDelegate: VisitMany<'a>; }

struct Unit;
impl VisitMany<'_> for Unit { type VisitOneDelegate = Unit; }
impl VisitOne<'_> for Unit { type VisitManyDelegate = Unit; }

struct Wrap<V>(std::marker::PhantomData<V>);
impl<'a, V: VisitMany<'a>> VisitMany<'a> for Wrap<V> { type VisitOneDelegate = Self; }
impl<'a, V: VisitMany<'a>> VisitOne<'a> for Wrap<V> { type VisitManyDelegate = Self; }

fn parse_document<'a, V: VisitMany<'a>>() { parse_node::<Wrap<V>>(); }
fn parse_node<'a, V: VisitOne<'a>>() { parse_document::<V::VisitManyDelegate>(); }

fn main() {
    parse_document::<Unit>();
}

```

The current output is:

```
error[[E0275]](https://doc.rust-lang.org/nightly/error-index.html#E0275): overflow evaluating the requirement `Unit: VisitMany<'_>`
   |
   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "128"]` attribute to your crate (`playground`)
note: required because of the requirements on the impl of `VisitMany<'_>` for `Wrap<Unit>`
  --> src/main.rs:11:28
   |
11 | impl<'a, V: VisitMany<'a>> VisitMany<'a> for Wrap<V> { type VisitOneDelegate = Self; }
   |                            ^^^^^^^^^^^^^     ^^^^^^^
   = note: 63 redundant requirements hidden
   = note: required because of the requirements on the impl of `VisitMany<'_>` for `Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Unit>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
note: required because of the requirements on the impl of `VisitOne` for `Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Unit>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
  --> src/main.rs:12:28
   |
12 | impl<'a, V: VisitMany<'a>> VisitOne<'a> for Wrap<V> { type VisitManyDelegate = Self; }
   |                            ^^^^^^^^^^^^     ^^^^^^^
```

If we remove the lifetimes, however: [[playground]](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=425487fd6a17e771ede444e5bff16b2a)

```rust
#![recursion_limit = "64"] // be nice to the playground

trait VisitMany     { type VisitOneDelegate: VisitOne    ; }
trait VisitOne     { type VisitManyDelegate: VisitMany    ; }

struct Unit;
impl VisitMany     for Unit { type VisitOneDelegate = Unit; }
impl VisitOne     for Unit { type VisitManyDelegate = Unit; }

struct Wrap<V>(std::marker::PhantomData<V>);
impl<    V: VisitMany    > VisitMany     for Wrap<V> { type VisitOneDelegate = Self; }
impl<    V: VisitMany    > VisitOne     for Wrap<V> { type VisitManyDelegate = Self; }

fn parse_document<    V: VisitMany    >() { parse_node::<Wrap<V>>(); }
fn parse_node<    V: VisitOne    >() { parse_document::<V::VisitManyDelegate>(); }

fn main() {
    parse_document::<Unit>();
}
```

```
error: reached the recursion limit while instantiating `parse_document::<Wrap<Wrap<Wrap<...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
  --> src/main.rs:15:40
   |
15 | fn parse_node<    V: VisitOne    >() { parse_document::<V::VisitManyDelegate>(); }
   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: `parse_document` defined here
  --> src/main.rs:14:1
   |
14 | fn parse_document<    V: VisitMany    >() { parse_node::<Wrap<V>>(); }
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: the full type name has been written to '/playground/target/debug/deps/playground-4cb6c968a6c7af86.long-type.txt'
```

These are both post monomorphization `build`-only errors. Ideally, the former would get the nice latter error, rather than spitting a giant recursive type obligation at the user.

I tagged this as <kbd>A-diagnostics</kbd> since that is the visible outcome but the solution is probably actually

@rustbot label +A-traits