Rustc taking very long to compile chained method calls on trait

This code might seem a bit pathological, but it's based on a project I'm working on. I have the following struct and trait:

#[derive(Clone)]
struct S<A: Clone,B: Clone> {
  a: A,
  b: B,
}
trait Foo: Clone {}

impl<A: Clone, B: Clone> Foo for S<A, B> {}

if I do something like this:

fn chain<X: Foo, T: Clone>(s: X, t: T) -> S<X,T> {
  S{a: s.clone(), b: t}
}
let t = S{a: "test", b: 45};
let x = chain(chain(chain(chain(chain(chain(chain(chain(chain(chain(chain(chain(chain(chain(t,2),2),2),2),2),2),2),2),2),2),2),2),2),2);

it compiles almost instantly. However if instead I implement the function as a method on the trait:

trait Foo: Clone {

  fn chain<T: Clone>(&self, t: T) -> S<Self, T> {
    S{a: self.clone(), b: t}
  }
}
let x = S{a: "test", b: 45}
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2)
  .chain(2);

it takes rustc several minutes to compile. In fact, it seems that each additional call to chain triples the compile time! When I run rustc with "Z time-passes", it (not surprisingly) appears all the time is spent in "type checking"

The end results from each approach have the exact same type (assuming the same number of function calls), so I'm wondering what exactly is rustc doing differently that causes my second example to take so long to compile? Also is there anything I can do to the trait method version to speed up compile time?

1 Like

It is a reported issue. Hopefully we can fix this! Maybe yours isn't exactly the same, there are similar issues but they all seem to bring the same buggy behavior.

2 Likes