Skip to content

Implicit argument list modifier affects overload resolution with explicit arguments #10526

Open
@milessabin

Description

@milessabin

The following fails with an ambiguous overload,

object Test extends App {
  class Foo
  class Bar extends Foo

  def overload(implicit foo: Foo): Unit = {}
  def overload(implicit bar: Bar): Unit = {}

  overload(new Bar)
}
/*
implicit-overload.scala:8: error: ambiguous reference to overloaded definition,
both method overload in object Test of type (implicit bar: Test.Bar)Unit
and  method overload in object Test of type (implicit foo: Test.Foo)Unit
match argument types (Test.Bar)
  overload(new Bar)
  ^
one error found
*/

However, remove the implicit argument list modifier and it compiles as expected,

object Test extends App {
  class Foo
  class Bar extends Foo

  def overload(foo: Foo): Unit = {}
  def overload(bar: Bar): Unit = {}

  overload(new Bar)
}

This is because the logic in Inferencer#isAsSpecific only compares the result types of method types with an implicit argument list.

I think that at least part of this logic is intended to handle implicit method selection rather than overload resolution per se, but is misplaced and should actually be moved to ImplicitSearch#improves where, as well as fixing this bug, we have opportunities to improve implicit method selection based on implicit argument lists.

This bug is also present in Dotty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions