diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala | 8 | ||||
-rw-r--r-- | src/library/scala/runtime/ScalaRunTime.scala | 30 |
2 files changed, 27 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index c855abd7fb..0917646f76 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -126,6 +126,13 @@ trait SyntheticMethods extends ast.TreeDSL { val method = syntheticMethod(nme.toString_, FINAL, makeNoArgConstructor(StringClass.tpe)) typer typed { DEF(method) === LIT(clazz.name.decode) } } + def moduleHashCodeMethod: Tree = { + val method = syntheticMethod(nme.hashCode_, FINAL, makeNoArgConstructor(IntClass.tpe)) + // The string being used as hashcode basis is also productPrefix. + val code = clazz.name.decode.hashCode + + typer typed { DEF(method) === LIT(code) } + } def forwardingMethod(name: Name, targetName: Name): Tree = { val target = getMember(ScalaRunTimeModule, targetName) @@ -262,6 +269,7 @@ trait SyntheticMethods extends ast.TreeDSL { ) // methods for case objects only def objectMethods = List( + Object_hashCode -> (() => moduleHashCodeMethod), Object_toString -> (() => moduleToStringMethod) ) // methods for both classes and objects diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 5a20b72fcd..4d5f783d61 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -177,18 +177,26 @@ object ScalaRunTime { def _hashCode(x: Product): Int = { import scala.util.MurmurHash._ val arr = x.productArity - var h = startHash(arr) - var c = startMagicA - var k = startMagicB - var i = 0 - while (i < arr) { - val elem = x.productElement(i) - h = extendHash(h, elem.##, c, k) - c = nextMagicA(c) - k = nextMagicB(k) - i += 1 + // Case objects have the hashCode inlined directly into the + // synthetic hashCode method, but this method should still give + // a correct result if passed a case object. + if (arr == 0) { + x.productPrefix.hashCode + } + else { + var h = startHash(arr) + var c = startMagicA + var k = startMagicB + var i = 0 + while (i < arr) { + val elem = x.productElement(i) + h = extendHash(h, elem.##, c, k) + c = nextMagicA(c) + k = nextMagicB(k) + i += 1 + } + finalizeHash(h) } - finalizeHash(h) } /** Fast path equality method for inlining; used when -optimise is set. |