Repository: rust
Issue: Rustc failed to compile code due to overflowing trait bound
Labels: A-trait-system,T-compiler,C-bug,T-types,fixed-by-next-solver

The following code triggers a endless type recursion in rustc while the underlying trait bounds on calling `assert_sql_conversion` are trivially satisfied. 

```rust
use std::marker::PhantomData;

struct ValuesClause<T, Tab> {
    _marker: PhantomData<(T, Tab)>,
}

struct Eq<T, U>(PhantomData<(T, U)>);

trait Insertable<T> {
    type Values;
}

impl<T, U> Insertable<T> for Eq<T, U> {
    type Values = ValuesClause<U, T>;
}

impl<'a, T, U> Insertable<T> for &'a Eq<T, U>
where
    Eq<T, &'a U>: Insertable<T>,
{
    type Values = <Eq<T, &'a U> as Insertable<T>>::Values;
}

impl<A, SA, Tab> Insertable<Tab> for (A,)
where
    A: Insertable<Tab, Values = ValuesClause<(SA,), Tab>>,
{
    type Values = ValuesClause<SA, Tab>;
}

impl<'a, A, Tab> Insertable<Tab> for &'a (A,)
where
    (&'a A,): Insertable<Tab>,
{
    type Values = <(&'a A,) as Insertable<Tab>>::Values;
}

struct Table;

struct Foo {
    a: i32,
    b: String,
}

impl<'a> Insertable<Table> for &'a Foo {
    type Values = (Eq<Table, &'a i32>, Eq<Table, &'a String>);
}

fn assert_sql_conversion<'a, T, R>(_r: &'a R)
where
    &'a R: Insertable<T>,
{
    todo!()
}

fn main() {
    assert_sql_conversion(&Foo {
        a: 42,
        b: String::from("foo"),
    });
}
```


([Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0e96e9944fa14ec7bdde0c953577f4fb), Note that this is a minimized example starting from the original diesel code, therefore some things there are just simplified to reproduce the issue)

Error message:
```
error[E0275]: overflow evaluating the requirement `&Eq<_, _>: Insertable<_>`
  --> src/main.rs:57:5
   |
49 | fn assert_sql_conversion<'a, T, R>(_r: &'a R)
   |    --------------------- required by a bound in this
50 | where
51 |     &'a R: Insertable<T>,
   |            ------------- required by this bound in `assert_sql_conversion`
...
57 |     assert_sql_conversion(&Foo {
   |     ^^^^^^^^^^^^^^^^^^^^^
   |
   = help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`playground`)
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&Eq<_, _>,)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(Eq<_, _>,)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(Eq<_, _>,),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((Eq<_, _>,),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((Eq<_, _>,),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((Eq<_, _>,),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((Eq<_, _>,),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((Eq<_, _>,),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((Eq<_, _>,),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((Eq<_, _>,),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((Eq<_, _>,),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((Eq<_, _>,),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((Eq<_, _>,),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((Eq<_, _>,),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((Eq<_, _>,),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((Eq<_, _>,),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((Eq<_, _>,),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((Eq<_, _>,),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((Eq<_, _>,),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((Eq<_, _>,),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((Eq<_, _>,),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((Eq<_, _>,),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((((Eq<_, _>,),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((((Eq<_, _>,),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((((Eq<_, _>,),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((((Eq<_, _>,),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((((((Eq<_, _>,),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((((((Eq<_, _>,),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&(((((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&((((((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `(&((((((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),),),),)`
   = note: required because of the requirements on the impl of `Insertable<_>` for `&(((((((((((((((((((((((((Eq<_, _>,),),),),),),),),),),),),),),),),),),),),),),),),)`
```