Skip to content

Case class hashing #10495

@ctongfei

Description

@ctongfei

Currently the hashing of case classes are synthesized, and their implementation is the same as scala.util.hashing.MurmurHash3.productHash.
This function takes into account the productPrefix only when the productArity is 0.

This produces the following problem:

scala> Left(1).##
res1: Int = 818387364

scala> Right(1).##
res2: Int = 818387364

Should productPrefix always be mixed into the hashCode by using productPrefix.## as the seed?

Implementation of scala.util.hashing.MurmurHash3.productHash:

  /** Compute the hash of a product */
  final def productHash(x: Product, seed: Int): Int = {
    val arr = x.productArity
    // 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 = seed // !!! I propose change this to "var h = x.productPrefix.hashCode"
      var i = 0
      while (i < arr) {
        h = mix(h, x.productElement(i).##)
        i += 1
      }
      finalizeHash(h, arr)
    }
  }

Related discussions on the Scala contributors site: https://contributors.scala-lang.org/t/case-class-hashing/1076

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions