immutable class can't override opEquals, workaround?

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Feb 20 23:58:42 PST 2016


On Sunday, February 21, 2016 04:25:59 SimonN via Digitalmars-d-learn wrote:
> Hi,
>
>      immutable class A {
>          int i;
>          this(int arg) { i = arg; }
>          override bool opEquals(Object rhsObj)
>          {
>              auto rhs = cast (immutable(A)) rhsObj;
>              return rhs && i == rhs.i;
>          }
>      }
>
> Error by dmd 2.070:
>
>      ./immutclass.d(4): Error: function immutclass.A.opEquals
>      does not override any function, did you mean to override
>      'object.Object.opEquals'?
>
> My understandings:
>
> 1.  immutable class A means: All methods have immutable tacked
>      on them implicitly.
> 2.  Object.opEquals doesn't have immutable tacked on it. If I
>      want to override Object.opEquals, I should override without
>      'immutable'.
> 3.  Overriding opEquals and toHash are necessary to make A
>      behave properly as AA key type. This is incompatible with
>      (2) in an immutable class.
> 4.  I found this thread:
>          How to turn an inout(Object) into a string
>
> http://forum.dlang.org/thread/dcobmtogyrmnaqnqyvbz@forum.dlang.org
>      that I interpret as: The need for the currently-impossible
>      override is acknowledged, but the implementation would bring
>      significant changes to the language, therefore the solution
>      is postponed. The above thread was from mid-2015, but I guess
>      it's still relevant.
>
> My workaround is: Make class _A private, and declare every method
> immutable, except for what Object decrees to be mutable/const/...
> Then make a public alias A = immutable(_A).
>
> Is there something better than this?
>
> Has there been any new development on Object method removal?
> Jonathan M Davis has been pushing this hard 2 years ago, I'd
> love to see the efforts make it into the language. :-)

Okay. Until opEquals, toHash, toString, and opCmp have been removed from
Object, you can't override any of them as anything other than mutable.
opEquals still works with const and immutable objects via a hack in druntime
(it casts away const inside of the free function opEquals which works if
your opEquals behaves but results in undefined behavior if it mutates
anything). So, I expect that it's simply not possible right now to use a
class as a key in an AA, though a struct should work if it's defined
appropriately. Certainly, if it's legal to use a class as the key in an AA,
it's a bug given that there's no guarantee that it's immutable like a key
needs to be.

As for actually getting rid of opEquals and friends from Object, no real
progress has been made. I finally have a working version of the PR to
templatize the free function opEquals such that it will work with opEquals
that take a derived class instead of Object (previously, compiler bugs kept
getting in the way of it working), but it hasn't even been looked at yet
from what I can tell, and it's the simplest of the bits that need to be done
(https://github.com/D-Programming-Language/druntime/pull/1439). The overhaul
of the AA implementation to templatize it needs to be completed (and I'm not
sure where it currently stands) and there will likely have to be some clever
compiler changes to make it so that we can remove those 4 functions from
Object without breaking code in the process. So, it's going to take a
variety of people to get it done, and unfortunately, it hasn't been high on
much of anyone's todo list.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list