Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Mix in theproductPrefix hash statically in case classhashCode#11023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lrytz merged 1 commit intoscala:2.13.xfromlrytz:t13033b
Apr 3, 2025

Conversation

@lrytz
Copy link
Member

@lrytzlrytz commentedMar 20, 2025
edited
Loading

Since 2.13, case classhashCode mixes in the hash code of theproductPrefix string. This is inconsistent with theequals method, subclasses of case classes that overrideproductPrefix compare equal but have a differenthashCode.

This commit changeshashCode to mix in theproductPrefix.hashCode statically instead of invokingproductPrefix at runtime.

For case classes without primitive fields, the synthetichashCode invokesScalaRunTime._hashCode, which mixes in the result ofproductPrefix. To fix that, the synthetic hashCode is changed to invokeMurmurHash3.productHash directly and mix in the name to the seed statically. This works out with keepingproductHash forwards and backwards compatible.

TheMurmurHash3.productHash method 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.

Fixesscala/bug#13033

@scala-jenkinsscala-jenkins added this to the2.13.17 milestoneMar 20, 2025
@lrytz
Copy link
MemberAuthor

The attemt to keepc.hashCode andMurmurHash3.productHash(c) in sync breaks because one depends on the compiler verison, the other on the runtime library version.

Not sure if that's a big issue...

@SethTisueSethTisue added the release-notesworth highlighting in next release notes labelMar 20, 2025
@lrytzlrytz changed the titleMixclassOf[C].getName instead ofproductPrefix in casehashCodeMix in theproductPrefix hash statically in case classhashCodeMar 21, 2025
@lrytzlrytzforce-pushed thet13033b branch 3 times, most recently from11b1efa to37a12baCompareMarch 21, 2025 13:44
@lrytzlrytzforce-pushed thet13033b branch 2 times, most recently from2ea7949 todedfce3CompareMarch 21, 2025 20:11
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` compareequal 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 changedto invoke `MurmurHash3.productHash` directly and mix in the nameto 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, thecase class name needs to be passed manually to `caseClassHash`.
}else {
if (arr==0)
if (!ignorePrefix) x.productPrefix.hashCodeelse seed
else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

rare case where I would retain extra braces (Scala 2)

defensureAccessible(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`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

"originally" here means like first verse of Genesis

lrytz added a commit to scala/scala3 that referenced this pull requestApr 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 equalbut 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 toinvoke `MurmurHash3.productHash` directly and mix in the name to theseed statically.Scala 3 forward port ofscala/scala#11023
@lrytzlrytz merged commit4345ced intoscala:2.13.xApr 3, 2025
3 checks passed
hamzaremmal pushed a commit to hamzaremmal/scala3 that referenced this pull requestMay 2, 2025
Mix in the `productPrefix` hash statically in case class `hashCode`
hamzaremmal pushed a commit to scala/scala3 that referenced this pull requestMay 7, 2025
Mix in the `productPrefix` hash statically in case class `hashCode`
dongjoon-hyun pushed a commit to apache/spark that referenced this pull requestOct 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?NoCloses#52509 from vrozov/SPARK-53585.Authored-by: Vlad Rozov <vrozov@amazon.com>Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
huangxiaopingRD pushed a commit to huangxiaopingRD/spark that referenced this pull requestNov 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?NoClosesapache#52509 from vrozov/SPARK-53585.Authored-by: Vlad Rozov <vrozov@amazon.com>Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@som-snyttsom-snyttsom-snytt left review comments

@sjrdsjrdsjrd approved these changes

Assignees

No one assigned

Labels

release-notesworth highlighting in next release notes

Projects

None yet

Milestone

2.13.17

Development

Successfully merging this pull request may close these issues.

OverridingproductPrefix breaks case class hash code

5 participants

@lrytz@som-snytt@sjrd@SethTisue@scala-jenkins

[8]ページ先頭

©2009-2025 Movatter.jp