Skip to content

Wrong overload resolution: picks Any over Long with an Int argument #7630

Closed
@sjrd

Description

@sjrd

minimized code

object Asserts {
  def assertEquals(expected: Any, actual: Any): Unit = {
    println(1)
    assert(expected.equals(actual), s"expected $expected but got $actual")
  }

  def assertEquals(expected: Long, actual: Long): Unit = {
    println(2)
    assert(expected == actual, s"expected $expected but got $actual")
  }
}

object Test {
  def main(args: Array[String]): Unit = {
    def foo(): Long = 42L

    Asserts.assertEquals(42, foo()) // an Int and a Long
  }
}

observed behavior

The first overload, taking Anys, is selected over the second one.

1
Exception in thread "main" java.lang.AssertionError: assertion failed: expected 42 but got 42
        at dotty.DottyPredef$.assertFail(DottyPredef.scala:17)
        at Asserts$.assertEquals(hello.scala:4)
        at Test$.main(hello.scala:17)
        at Test.main(hello.scala)

expectation

Like in Scala 2, the second overload, taking Longs, should be selected, so that it prints:

2

note

The API of Asserts above is defined in JUnit; it cannot be changed.

workaround

We can work around the issue by making sure that both arguments truly are Longs:

object Test {
  def main(args: Array[String]): Unit = {
    def foo(): Long = 42L

    Asserts.assertEquals(42L, foo()) // Long and Long
  }
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions