Why does it matter if opCmp is defined and not toHash? It's if opEquals is defined that toHash is required, not opCmp.
Comment #2 by jack — 2018-03-28T17:16:17Z
(In reply to Jonathan M Davis from comment #1)
> Why does it matter if opCmp is defined and not toHash? It's if opEquals is
> defined that toHash is required, not opCmp.
If opCmp is defined but opEquals isn't, doesn't DMD re-write `val == val` to `val.opCmp(val) == 0`?
Comment #3 by issues.dlang — 2018-03-28T17:24:06Z
(In reply to Jack Stouffer from comment #2)
> If opCmp is defined but opEquals isn't, doesn't DMD re-write `val == val` to
> `val.opCmp(val) == 0`?
No. The only way to override == and != is opEquals. e.g. this code runs and passes just fine:
struct S
{
int opCmp(S rhs)
{
assert(0);
}
}
void main()
{
assert(S.init == S.init);
}
If opCmp is consistent with the default opEquals, then there is no need to define opEquals, and opCmp will never be called for == or !=. If opCmp is not consistent with the default opEquals, then opEquals needs to be defined. And if opEquals is defined, then toHash needs to be defined. But as long as opEquals isn't defined, then the default toHash should work just fine.