I'm writing a program with bunch of structs/enums (no surprise). I'm planning to generalize these types to allow having extra information Wrapped<T>
while keep wrapped as generic. The goal is to have some context information when parsing T
, while I can keep using T
when generating it on memory.
trait X { type Wrapped<T>; }
struct Foo<T: X> {
bar: T::Wrapped<Bar>,
}
trait IdentX { type Wrapped<T> = T; }
trait WithBoolX {type Wrapped<T> = (T, bool); }
...
With this, you can statically creates Foo
with/without bool
context, without duplicating codes. See actual details in the playground below:
The problem is, if we want to derive Debug
(or any other ones like PartialEq
or PartialOrd
) on Foo
, the compiler requires X
trait itself to be Debug
, not only <T as X>::Wrapped
.
It'd make sense for regular trait (such as Option<T>
implementing Debug
only when T
is Debug
), but now I need to define all required trait bounds on Wrapped
for the X
and its impls, such as IdentX: Debug+PartialEq+Eq + ...
. It's nice if I can remove these nonsense bounds as actually X
is just a tag to instruct the compiler choosing Wrapped
. Is there a way to instruct compiler to tell this T: X
won't be used in the actual values thus don't be needed in trait impl bound?
BTW, as I only want 2 kind of X
impl (one for ident, one for tracking parser position), it'd be also nice if I can work around without using GATs if it gets simpler overall. This complication may come from abusing GATs as higher-kinded type.