From 12453a7477dab4f32655bf12fbbc9936ed96f0e6 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 15 Jan 2018 16:02:35 +0100 Subject: [PATCH] Fix #3106: Pre-compute hash for case classes with 0 parameters --- .../dotc/transform/SyntheticMethods.scala | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala b/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala index d2ca704d3612..89c566036bdc 100644 --- a/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala @@ -214,12 +214,19 @@ class SyntheticMethods(thisPhase: DenotTransformer) { * ``` */ 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(clazz.fullName.toString.hashCode))) - val mixes = for (accessor <- accessors.toList) yield - Assign(ref(acc), ref(defn.staticsMethod("mix")).appliedTo(ref(acc), hashImpl(accessor))) - val finish = ref(defn.staticsMethod("finalizeHash")).appliedTo(ref(acc), Literal(Constant(accessors.size))) - Block(accDef :: mixes, finish) + val seed = clazz.fullName.toString.hashCode + if (accessors.nonEmpty) { + val acc = ctx.newSymbol(ctx.owner, "acc".toTermName, Mutable | Synthetic, defn.IntType, coord = ctx.owner.pos) + val accDef = ValDef(acc, Literal(Constant(seed))) + val mixes = for (accessor <- accessors) yield + Assign(ref(acc), ref(defn.staticsMethod("mix")).appliedTo(ref(acc), hashImpl(accessor))) + val finish = ref(defn.staticsMethod("finalizeHash")).appliedTo(ref(acc), Literal(Constant(accessors.size))) + Block(accDef :: mixes, finish) + } else { + // Pre-compute the hash code + val hash = scala.runtime.Statics.finalizeHash(seed, 0) + Literal(Constant(hash)) + } } /** The `hashCode` implementation for given symbol `sym`. */