Aladdin - Scala Bugtracking
[#551] project: compiler priority: medium category: bug
submitter assigned to status date submitted
Burak Martin fixed 2006-03-17 03:17:18.0
subject ScalaRuntime._equals erroneous
code
case class A(x:int);
class B(x:int) extends A(x);
what happened
The ScalaRuntime._equals method is called to test structural equality of case classes.

It starts happily with (x.getClass() eq y.getClass()) && ... children equal to.

Unfortunately, consider this:

then B(3) should equal A(3), but it doesn't.
what expected Proper structural equality that follows inheritance.
[back to overview]
Changes of this bug report
Martin  edited on  2006-03-17 19:46:55.0
I am not sure. I think in this case we should pick the definition that is easier to spec. The current one reads: Two instances of case classes A(xs), B(ys) are equal if A == B and xs == ys. How do you spec the proposed change? And, what other motivation is there to change? -- Martin
Burak  edited on  2006-03-17 22:29:44.0

oh, I was referring to the now outdated spec and was assuming that this part would not have changed.

The right thing to do (spec and impl) is obviously "if (A <: B or B <: A) and xs==ys" where either A or B is a case class, then the instances are equal

Surprise, this would then translate to the following code:

val xc = x.getClass(); val yc = y.getClass(); (xc.isAssignableFrom(yc) || yc.isAssignableFrom(xc)) && xs==ys

(I must admit that java.lang.Class method has a mystifying name)

I can't recollect whether case classes participate in mixin composition. Depending on how we compile case classes, it might be necessary to go to a super-interface for that assignableFrom check (since a Scala class becomes a Java class and a Java interface). Otherwise, the equal method would not be symmetric.

Burak  edited on  2006-03-17 22:36:07.0

Answering "what other motivation", well to use the above method would prevent some existing code from breaking and would preserve the Liskov Substitution Principle(tm) : )

Martin  edited on  2006-05-27 11:34:39.0
This is finally put to rest now.