@@ -3,7 +3,7 @@ package transform
3
3
4
4
import ast .tpd
5
5
import core ._
6
- import Contexts ._ , Symbols ._
6
+ import Contexts ._ , Symbols ._ , Types . _ , Flags . _ , Phases . _
7
7
import DenotTransformers ._ , MegaPhase ._
8
8
import TreeExtractors ._ , ValueClasses ._
9
9
@@ -23,13 +23,18 @@ class VCElideAllocations extends MiniPhase with IdentityDenotTransformer {
23
23
override def runsAfter : Set [String ] = Set (ElimErasedValueType .name)
24
24
25
25
override def transformApply (tree : Apply )(using Context ): Tree =
26
+ def hasUserDefinedEquals (tp : Type ): Boolean =
27
+ val eql = atPhase(erasurePhase) {
28
+ defn.Any_equals .matchingMember(tp.typeSymbol.thisType)
29
+ }
30
+ eql.owner != defn.AnyClass && ! eql.is(Synthetic )
26
31
tree match {
27
- // new V(u1) == new V(u2) => u1 == u2
32
+ // new V(u1) == new V(u2) => u1 == u2, unless V defines its own equals.
28
33
// (We don't handle != because it has been eliminated by InterceptedMethods)
29
34
case BinaryOp (NewWithArgs (tp1, List (u1)), op, NewWithArgs (tp2, List (u2)))
30
- if (tp1 eq tp2) && (op eq defn.Any_== ) &&
31
- isDerivedValueClass(tp1.typeSymbol) &&
32
- ! defn. Any_equals .overridingSymbol (tp1.typeSymbol.asClass).exists =>
35
+ if (tp1 eq tp2) && (op eq defn.Any_== )
36
+ && isDerivedValueClass(tp1.typeSymbol)
37
+ && ! hasUserDefinedEquals (tp1) =>
33
38
// == is overloaded in primitive classes
34
39
u1.equal(u2)
35
40
0 commit comments