I've tried to emulate GAT by using an intermediate builder trait like this:
trait Foo: Sized {
type AssocBuilder: BuildAssoc<'static, Foo = Self>; // removing the bound allows this to be compiled
fn build_assoc<'a>(&'a self) -> <Self::AssocBuilder as BuildAssoc<'a>>::Assoc
where
Self::AssocBuilder: BuildAssoc<'a, Foo = Self>
{
<Self::AssocBuilder as BuildAssoc<'a>>::build_assoc(self)
}
}
trait BuildAssoc<'a> {
type Foo: Foo;
type Assoc: 'a;
fn build_assoc(foo: &'a Self::Foo) -> Self::Assoc;
}
I've required a trait bound for Foo::AssocBuilder
to improve ergonomics in case the trait is used for global Foo
s (common use case), but this fails to compile with:
error[E0284]: type annotations needed
--> src/lib.rs:4:5
|
4 | / fn build_assoc<'a>(&'a self) -> <Self::AssocBuilder as BuildAssoc<'a>>::Assoc
5 | | where
6 | | Self::AssocBuilder: BuildAssoc<'a, Foo = Self>
7 | | {
8 | | <Self::AssocBuilder as BuildAssoc<'a>>::build_assoc(self)
9 | | }
| |_____^ cannot infer type for associated type `<Self as Foo>::AssocBuilder`
|
= note: cannot resolve `<<Self as Foo>::AssocBuilder as BuildAssoc<'a>>::Assoc == _`
When I remove the trait bound for Foo::AssocBuilder
the code compiles, but I don't understand why the type can supposedly not be inferred otherwise, since I very explicitly state all involved types and lifetimes.