Why is it necessary to specify lifetimes of intermediate GATs?

Is it possible to somehow make this compile? If not, is that a current limitation of the compiler or is the code ambiguous?

trait Foo {
    type Bar<'a>: Bar;
}

trait Bar {
    type Baz: 'static;
}

struct FooBaz<F: Foo> {
    baz: <F::Bar<'_> as Bar>::Baz,
    // .. other fields that make it impossible to be generic over <B: Bar>
}

Playground.

Since lifetime specialization is effectively banned so I think this theoretically could compile. But this requires deduction logic not present in the compiler.

I think an easier way to get what you want is do something like this:

trait Foo {
    type Bar<'a>: Bar<Baz = Self::Baz>;
    type Baz;
}

trait Bar {
    type Baz: 'static;
}

struct FooBaz<F: Foo> {
    baz: <F as Foo>::Baz,
}

... which effectively guide the compiler that Baz is unique.

2 Likes