My last post mentioned that a change to a Structural template caused a unittest failure. The specific details are as follows.
Human h1 = new Human();
// structural upcast (two steps)
Quack qx = h1.wrap!Quack; // Human -> Quack
Flyer fx = qx.wrap!Flyer; // Quack -> Flyer
// strucural downcast (two steps)
Quack qy = fx.unwrap!Quack; // Flyer -> Quack
Human hy = qy.unwrap!Human; // Quack -> Human
assert(hy is h1);
// strucural downcast (one step)
Human hz = fx.unwrap!Human; // Flyer -> Human
assert(hz is h1); // FAIL
The failure was on the direct step from a Flyer straight back to a Human. The Flyer object did not wrap a Human, instead it was a Quack. But the change to use Structural!T doesn't know anything about Quack. This meant that checking if the Flyer could be cast to a Structural!Human would fail because it was not. Templates in D are not contravariant so the Flyer was also not a Structural!Object, even though for all intents and purposes it is.
I believe there is some classinfo I could obtain and setup appropriate calls to make the appropriate jumps back to the original type. However, I can have the compiler do this for me. So I returned to the original object approach by making classes and interfaces use Structural!Object and leave the specific type only for structs.
This is a workable solution since a structure will never nest. If a struct is wrapped into multiple types, the second wrap will be wrapping the Impl class created from the first
On a similar note, I found a request by Andrei which I think is essentially addressed by this work, Class!T.