Try to attach extra information statically & conditionally

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.

No, the built-in derive doesn't do that. Implement manually.


BTW, it's wrong to implement Display in terms of Debug. Display must be stable (breakig Display is a breaking change), whereas Debug isn't.

2 Likes

That's unfortunate, but that'd also make sense. probably I'd choose to have unnecessary bound on the trait though as it'd be cumbersome to define various derived methods.

Thanks for pointing, as you pointed it was not a good snippet.

https://crates.io/crates/derive-where

FYI, I found the perfect crate which allows me to use speicific trait bound