Consider a code like this (of course, this is an extremely simplified version of what I really have):
trait A {}
trait B<T: A> {
fn get_a() -> T;
}
struct C<U, T>
where
T: A,
U: B<T>,
{
field: U,
}
The compiler throws a [E0392] error because it thinks the type parameter T of C is unused. However, it is completely necessary to specify that U's type parameter meets the trait constraint.
In my use case, B is a factory that creates A's. A concrete factory will always create the same type of struct implementing A, that's why I do not use a Box.
I can work around this by adding a PhantomData field to the struct, but shouldn't the compiler notice that T is needed? Is there another approach to achieve something like that?
Shouldn't T be an associated type inside B and not a type parameter? Currently, it's possible to have U: B<T1> and U: B<T2> at the same time - does this make sense from your point of view?
Thanks @Cerber-Ursi and @alice. Surely the associated type version is a better approach to my use case. It captures the fact that a B will always produce the same type of A.
I still wonder why the original code requires the PhantomData (guess there's some other use case where code like that makes sense). What arnaudgolfouse says makes sense, the compiler needs to know whether C is covariant, contrabariant or invariant over T.