Mix in the productPrefix hash statically in case class hashCode#11023
Merged
Conversation
Member
Author
|
The attemt to keep Not sure if that's a big issue... |
This was referenced Mar 20, 2025
sjrd
reviewed
Mar 20, 2025
classOf[C].getName instead of productPrefix in case hashCodeproductPrefix hash statically in case class hashCode
sjrd
reviewed
Mar 21, 2025
11b1efa to
37a12ba
Compare
sjrd
approved these changes
Mar 21, 2025
2ea7949 to
dedfce3
Compare
Since 2.13, case class `hashCode` mixes in the hash code of the `productPrefix` string. This is inconsistent with the `equals` method, subclasses of case classes that override `productPrefix` compare equal but have a different `hashCode`. This commit changes `hashCode` to mix in the `productPrefix.hashCode` statically instead of invoking `productPrefix` at runtime. For case classes without primitive fields, the synthetic `hashCode` invokes `ScalaRunTime._hashCode`, which mixes in the result of `productPrefix`. To fix that, the synthetic hashCode is changed to invoke `MurmurHash3.productHash` directly and mix in the name to the seed statically. This works out with keeping `productHash` forwards and backwards compatible. The `MurmurHash3.productHash` method is deprecated / renamed to `caseClassHash`. This method computes the same hash as the synthetic `hashCode`, except for the corner case where a case class (or a subclass) override the `productPrefix`. In this case, the case class name needs to be passed manually to `caseClassHash`.
som-snytt
reviewed
Mar 24, 2025
| } else { | ||
| if (arr == 0) | ||
| if (!ignorePrefix) x.productPrefix.hashCode else seed | ||
| else { |
Contributor
There was a problem hiding this comment.
rare case where I would retain extra braces (Scala 2)
som-snytt
reviewed
Mar 24, 2025
| def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) | ||
|
|
||
| // This is called by the synthetic case class `toString` method. | ||
| // It originally had a `CaseClass` parameter type which was changed to `Product`. |
Contributor
There was a problem hiding this comment.
"originally" here means like first verse of Genesis
lrytz
added a commit
to scala/scala3
that referenced
this pull request
Apr 3, 2025
…22865) Since 2.13, case class `hashCode` mixes in the hash code of the `productPrefix` string. This is inconsistent with the `equals` method, subclasses of case classes that override `productPrefix` compare equal but have a different `hashCode` (scala/bug#13033). This commit changes `hashCode` to mix in the `productPrefix.hashCode` statically instead of invoking `productPrefix` at runtime. For case classes without primitive fields, the synthetic `hashCode` invokes `ScalaRunTime._hashCode`, which mixes in the result of `productPrefix`. To fix that, the synthetic hashCode is changed to invoke `MurmurHash3.productHash` directly and mix in the name to the seed statically. Scala 3 forward port of scala/scala#11023
hamzaremmal
pushed a commit
to hamzaremmal/scala3
that referenced
this pull request
May 2, 2025
Mix in the `productPrefix` hash statically in case class `hashCode`
hamzaremmal
pushed a commit
to scala/scala3
that referenced
this pull request
May 7, 2025
Mix in the `productPrefix` hash statically in case class `hashCode`
dongjoon-hyun
pushed a commit
to apache/spark
that referenced
this pull request
Oct 13, 2025
### What changes were proposed in this pull request? Upgrade to scala 2.13.17 ### Why are the changes needed? To bring the latest bug fixes and improvements like JDK 25 support. Note that Scala community announces two breaking changes due to the bug fixes. > Breaking changes > - Mix in the productPrefix hash statically in case class hashCode > - Improve scala.util.Using suppression order - https://github.com/scala/scala/releases/tag/v2.13.17 - scala/scala#11046 - scala/scala#10937 - scala/scala#10927 - scala/bug#13058 - scala/scala#11023 - scala/bug#13033 - scala/scala#11000 ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? local and github builds ### Was this patch authored or co-authored using generative AI tooling? No Closes #52509 from vrozov/SPARK-53585. Authored-by: Vlad Rozov <[email protected]> Signed-off-by: Dongjoon Hyun <[email protected]>
This was referenced Nov 25, 2025
huangxiaopingRD
pushed a commit
to huangxiaopingRD/spark
that referenced
this pull request
Nov 25, 2025
### What changes were proposed in this pull request? Upgrade to scala 2.13.17 ### Why are the changes needed? To bring the latest bug fixes and improvements like JDK 25 support. Note that Scala community announces two breaking changes due to the bug fixes. > Breaking changes > - Mix in the productPrefix hash statically in case class hashCode > - Improve scala.util.Using suppression order - https://github.com/scala/scala/releases/tag/v2.13.17 - scala/scala#11046 - scala/scala#10937 - scala/scala#10927 - scala/bug#13058 - scala/scala#11023 - scala/bug#13033 - scala/scala#11000 ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? local and github builds ### Was this patch authored or co-authored using generative AI tooling? No Closes apache#52509 from vrozov/SPARK-53585. Authored-by: Vlad Rozov <[email protected]> Signed-off-by: Dongjoon Hyun <[email protected]>
This was referenced Jan 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since 2.13, case class
hashCodemixes in the hash code of theproductPrefixstring. This is inconsistent with theequalsmethod, subclasses of case classes that overrideproductPrefixcompare equal but have a differenthashCode.This commit changes
hashCodeto mix in theproductPrefix.hashCodestatically instead of invokingproductPrefixat runtime.For case classes without primitive fields, the synthetic
hashCodeinvokesScalaRunTime._hashCode, which mixes in the result ofproductPrefix. To fix that, the synthetic hashCode is changed to invokeMurmurHash3.productHashdirectly and mix in the name to the seed statically. This works out with keepingproductHashforwards and backwards compatible.The
MurmurHash3.productHashmethod is deprecated / renamed tocaseClassHash. This method computes the same hash as the synthetichashCode, except for the corner case where a case class (or a subclass) override theproductPrefix. In this case, the case class name needs to be passed manually tocaseClassHash.Fixes scala/bug#13033