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?