Skip to content

Commit 413b9c6

Browse files
committed
Fix optimization in VCElideAllocations
We should not optimize new V(x) == new V(y) to x == y if value class `V` redefines `equals`.
1 parent 41a33cd commit 413b9c6

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import ExtensionMethods._, TreeExtractors._, ValueClasses._
1212
* For a value class V defined as:
1313
* class V(val underlying: U) extends AnyVal
1414
* we avoid unnecessary allocations:
15-
* new V(u1) == new V(u2) => u1 == u2
15+
* new V(u1) == new V(u2) => u1 == u2 provided V does not redefine `equals`
1616
* (new V(u)).underlying() => u
1717
*/
1818
class VCElideAllocations extends MiniPhase with IdentityDenotTransformer {
@@ -27,7 +27,9 @@ class VCElideAllocations extends MiniPhase with IdentityDenotTransformer {
2727
// new V(u1) == new V(u2) => u1 == u2
2828
// (We don't handle != because it has been eliminated by InterceptedMethods)
2929
case BinaryOp(NewWithArgs(tp1, List(u1)), op, NewWithArgs(tp2, List(u2)))
30-
if (tp1 eq tp2) && (op eq defn.Any_==) && isDerivedValueClass(tp1.typeSymbol) =>
30+
if (tp1 eq tp2) && (op eq defn.Any_==) &&
31+
isDerivedValueClass(tp1.typeSymbol) &&
32+
!defn.Any_equals.overridingSymbol(cls).exists =>
3133
// == is overloaded in primitive classes
3234
u1.equal(u2)
3335

tests/run/vc-equals.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
object Test extends App {
2+
3+
class C(val s: Array[Int]) extends AnyVal {
4+
override def equals(that: Any) = that match {
5+
case that: C => s.deep == that.s.deep
6+
case _ => false
7+
}
8+
}
9+
10+
val c = new C(Array(1, 2,3))
11+
12+
assert(c `equals` new C(Array(1, 2, 3)))
13+
assert(c == (new C(Array(1, 2, 3)): Any))
14+
assert(c == new C(Array(1, 2, 3)))
15+
16+
}

0 commit comments

Comments
 (0)