Overflow on requirement evaluation with associated types

00e9629
Opened by ebfull at 2024-12-21 05:10:38
trait Foo { }

trait Bar<P> {
    type X;
}

impl<T, U> Foo for (T, U)
    where T: Bar<(T, U), X=U>
{ }

impl<T, P: Foo> Bar<P> for T {
    type X = u32;
}

fn main() { }

produces on stable and nightly:

error[E0275]: overflow evaluating the requirement `<T as Bar<(T, U)>>::X`
 --> src/lol.rs:7:1
  |
7 |   impl<T, U> Foo for (T, U)
  |  _^ starting here...
8 | |     where T: Bar<(T, U), X=U>
9 | | { }
  | |___^ ...ending here
  |
  = note: required because of the requirements on the impl of `Foo` for `(T, U)`
  = note: required because of the requirements on the impl of `Bar<(T, U)>` for `T`

error: aborting due to previous error

The impl's compile individually but not together. I expect it to be able to compile.

  1. Note that in the absense of associated types, the above works fine.

    You can cheat (for some reason?) and put a bound on T in the Bar<P> impl, but you just end up running into the same overflow somewhere else:

    trait Foo {
        fn whatever() { }
    }
    
    trait Bar<P> {
        type X;
    }
    
    trait Baz { }
    impl Baz for usize { }
    
    impl<T, U> Foo for (T, U)
        where T: Bar<(T, U), X=U>
    { }
    
    impl<T: Baz, P: Foo> Bar<P> for T {
        type X = u32;
    }
    
    fn main() {
        <(usize, u32) as Foo>::whatever();
    }
    

    produces

    error[E0275]: overflow evaluating the requirement `(usize, u32): Foo`
      --> <anon>:21:5
       |
    21 |     <(usize, u32) as Foo>::whatever();
       |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = note: required by `Foo::whatever`
    
    error: aborting due to previous error
    

    ebfull at 2017-03-17 03:21:18

  2. Triage: this still overflows.

    Steve Klabnik at 2020-03-27 13:34:22