There are other solutions.
For example remove the current opEquals from structs, so doing == among two
structs become a syntax error. And then add a property like @equable that when
present beside the struct name adds a specific and correct and recursive
opEquals to it.
@equable stuct Foo {
int x;
}
Probably instead of @equable it's better to have an attribute that adds opHash,
opEquals and opCmp to a struct.
This is safe, avoids most code bloat, and keeps code fast. The disadvantage is
a that it adds a new attribute to the language.
If the user can create new attributes, then it's surely possible to define this
attribute with D code and some compile-time reflection, keeping the language
simple enough. There is one or more Java libs that use attributes for this
specific purpose.
Bye,
bearophile