Skip to content

Rustc failed to compile code due to overflowing trait bound #78982

Open
@weiznich

Description

@weiznich

The following code triggers a endless type recursion in rustc while the underlying trait bounds on calling assert_sql_conversion are trivially satisfied.

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, 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<_, _>,),),),),),),),),),),),),),),),),),),),),),),),),)`

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-trait-systemArea: Trait systemC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions