From b1d6de2e8293c78571d85c09968a26c67cc96619 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Sun, 15 Feb 2015 00:03:58 +0100 Subject: Fix hashCode method for value classes Before this commit, we used the same implementation than for case classes. After this commit, we use the hashCode of the underlying type as defined in SIP-15. --- .../tools/dotc/transform/SyntheticMethods.scala | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/dotty/tools/dotc/transform/SyntheticMethods.scala b/src/dotty/tools/dotc/transform/SyntheticMethods.scala index 5b27eadd9..4726105c6 100644 --- a/src/dotty/tools/dotc/transform/SyntheticMethods.scala +++ b/src/dotty/tools/dotc/transform/SyntheticMethods.scala @@ -76,7 +76,8 @@ class SyntheticMethods extends MiniPhaseTransform with IdentityDenotTransformer ref(defn.runtimeMethod("_" + sym.name.toString)).appliedToArgs(This(clazz) :: vrefss.head) def syntheticRHS(implicit ctx: Context): List[List[Tree]] => Tree = synthetic.name match { - case nme.hashCode_ => vrefss => hashCodeBody + case nme.hashCode_ if isDerivedValueClass(clazz) => vrefss => valueHashCodeBody + case nme.hashCode_ => vrefss => caseHashCodeBody case nme.toString_ => forwardToRuntime case nme.equals_ => vrefss => equalsBody(vrefss.head.head) case nme.canEqual_ => vrefss => canEqualBody(vrefss.head.head) @@ -120,11 +121,24 @@ class SyntheticMethods extends MiniPhaseTransform with IdentityDenotTransformer } } + /** The class + * + * class C(x: T) extends AnyVal + * + * gets the hashCode method: + * + * def hashCode: Int = x.hashCode() + */ + def valueHashCodeBody(implicit ctx: Context): Tree = { + assert(accessors.length == 1) + ref(accessors.head).select(nme.hashCode_).ensureApplied + } + /** The class * * case class C(x: T, y: T) * - * get the hashCode method: + * gets the hashCode method: * * def hashCode: Int = { * var acc: Int = 0xcafebabe; @@ -133,7 +147,7 @@ class SyntheticMethods extends MiniPhaseTransform with IdentityDenotTransformer * Statics.finalizeHash(acc, 2) * } */ - def hashCodeBody(implicit ctx: Context): Tree = { + def caseHashCodeBody(implicit ctx: Context): Tree = { val acc = ctx.newSymbol(ctx.owner, "acc".toTermName, Mutable | Synthetic, defn.IntType, coord = ctx.owner.pos) val accDef = ValDef(acc, Literal(Constant(0xcafebabe))) val mixes = for (accessor <- accessors.toList) yield -- cgit v1.2.3