playground
In the demo below, A doesn't implement Debug, but all B<T> implements Debug, so I expect that all types that uses any B<T> can derive Debug, but it't not true. C<T> wrappes B<T> and derives Debug, but it seems that not all C<T> implements Debug, because D, which uses C<A>, can't derive Debug.
I want to know that is there a way to do something with B, that can recover the ability to derive Debug?
No. ... Kind of. I know there is some degree of support for specialisation, which might work, but it's unstable and you shouldn't be using it outside of helping test the feature. Unstable features can change or be removed at any time without warning, and aren't subject to backward compatibility guarantees.
If you want to ensure that T doesn't restrict the implementation of Debug for C<T>, then you need to implement Debug yourself. There might be a crate that does this for you, but I'm not aware of one. If you have to do this with a lot of types, you could also try implementing a procedural macro yourself.
it's a limitation of the Debug derive macro when generic is involved. the problem is in the C type, not the D type.
because the C type has T as generic parameter, the derive macro expands into something like:
impl<T: Debug> Debug for C<T> {
//...
}
note the T: Debug bounds, it is there to simplify the derive macro. otherwise, it need to parse every struct fields type to add "perfect" bounds, something like this:
impl<T> Debug for C<T> where B<T>: Debug {
//...
}
see "perfect derive":
in your example, you can manually derive Debug for the C<T> struct, then the D struct (which is not generic) can be derived without problem.
alternatively, you can use an intermediate type (_C in the following snippet) just for the purpose of derive macro with generics, and use a type alias (or newtype) as the "real" type (the C type alias in the example):