Skip to content

Commit 05c5050

Browse files
mboveltgodzik
authored andcommitted
Make hashcode of enum items stable
Co-authored-by: anna herlihy <[email protected]> Co-authored-by: Miguel Trigueira <[email protected]> [Cherry-picked 8ea1261]
1 parent 8aaafef commit 05c5050

File tree

3 files changed

+15
-8
lines changed

3 files changed

+15
-8
lines changed

compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
6868
myCaseSymbols = defn.caseClassSynthesized
6969
myCaseModuleSymbols = myCaseSymbols.filter(_ ne defn.Any_equals)
7070
myEnumValueSymbols = List(defn.Product_productPrefix)
71-
myNonJavaEnumValueSymbols = myEnumValueSymbols :+ defn.Any_toString :+ defn.Enum_ordinal
71+
myNonJavaEnumValueSymbols = myEnumValueSymbols :+ defn.Any_toString :+ defn.Enum_ordinal :+ defn.Any_hashCode
7272
}
7373

7474
def valueSymbols(using Context): List[Symbol] = { initSymbols; myValueSymbols }
@@ -110,6 +110,12 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
110110
def syntheticDefIfMissing(sym: Symbol): List[Tree] =
111111
if (existingDef(sym, clazz).exists) Nil else syntheticDef(sym) :: Nil
112112

113+
def identifierRef: Tree =
114+
if isSimpleEnumValue then // owner is `def $new(_$ordinal: Int, $name: String) = new MyEnum { ... }`
115+
ref(clazz.owner.paramSymss.head.find(_.name == nme.nameDollar).get)
116+
else // assume owner is `val Foo = new MyEnum { def ordinal = 0 }`
117+
Literal(Constant(clazz.owner.name.toString))
118+
113119
def syntheticDef(sym: Symbol): Tree = {
114120
val synthetic = sym.copy(
115121
owner = clazz,
@@ -129,12 +135,6 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
129135
else
130136
identifierRef
131137

132-
def identifierRef: Tree =
133-
if isSimpleEnumValue then // owner is `def $new(_$ordinal: Int, $name: String) = new MyEnum { ... }`
134-
ref(clazz.owner.paramSymss.head.find(_.name == nme.nameDollar).get)
135-
else // assume owner is `val Foo = new MyEnum { def ordinal = 0 }`
136-
Literal(Constant(clazz.owner.name.toString))
137-
138138
def ordinalRef: Tree =
139139
if isSimpleEnumValue then // owner is `def $new(_$ordinal: Int, $name: String) = new MyEnum { ... }`
140140
ref(clazz.owner.paramSymss.head.find(_.name == nme.ordinalDollar_).get)
@@ -322,7 +322,8 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
322322
* For case classes with primitive paramters, see [[caseHashCodeBody]].
323323
*/
324324
def chooseHashcode(using Context) =
325-
if (accessors.isEmpty) Literal(Constant(ownName.hashCode))
325+
if (isNonJavaEnumValue) identifierRef.select(nme.hashCode_).appliedToTermArgs(Nil)
326+
else if (accessors.isEmpty) Literal(Constant(ownName.hashCode))
326327
else if (accessors.exists(_.info.finalResultType.classSymbol.isPrimitiveValueClass))
327328
caseHashCodeBody
328329
else
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
65
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
enum E:
2+
case A
3+
4+
@main def Test =
5+
println(E.A.hashCode)

0 commit comments

Comments
 (0)