scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.81k stars 1.05k forks source link

Overloading resolution incorrectly drops alternative with match type result when a target type is provided #21410

Open smarter opened 3 weeks ago

smarter commented 3 weeks ago

Compiler version

a2c53a16770ffb1d2f3929b74824402300c612eb

Minimized code

(Minimized from the two map methods in https://github.com/aherlihy/tyql/blob/expr-shape/src/main/scala/repro/overloadedmap.scala that lead to q2 not compiling).

object Test:
  def foo[T](x: Option[T]): T = ???
  def foo[T <: Tuple](x: T): Tuple.Map[T, List] = ???

  val tup: (Int, String) = (1, "")

  val x = foo(tup)
  val y: (List[Int], List[String]) = x

  val x2: (List[Int], List[String]) = foo(tup) // error

Output

10 |  val x2: (List[Int], List[String]) = foo(tup)
   |                                          ^^^
   |                             Found:    (Test.tup : (Int, String))
   |                             Required: Option[(List[Int], List[String])]

Expectation

x2 should behave like x: overloading resolution should end up using the second overload since the first is clearly not appicable.

The overloading changes in https://github.com/scala/scala3/pull/20054 do not have an impact on this issue (/cc @EugeneFlesselle).

EugeneFlesselle commented 2 weeks ago

Minimized a bit further:

class A
type F[X] <: Any = X match
  case A => Int

def foo[T](x: String): T = ???
def foo[U](x: U): F[U] = ???

val x1 = foo(A())
val y: Int = x1

val x2: Int = foo(A()) // error