Skip to content

Type inference failure while picking among conversions #13102

Open
@vhminh

Description

@vhminh

Reproduction steps

Scala version: 2.13.16

//> using scala 2.13.16
import scala.language.implicitConversions

trait LowPriorityConversions {
  implicit def convertIterable1[A, I[T] <: Iterable[T]](iterable: I[A]): String = {
    "convertIterable1 wins"
  }

  // implicit def convertIterable2[A, I[_]](iterable: I[A])(implicit ev: I[A] <:< Iterable[A]): String = {
  //   "convertIterable2 wins"
  // }
}

object Conversions extends LowPriorityConversions {
  implicit def convertMap[K, V, M[A, B] <: Map[A, B]](map: M[K, V]): String = {
    "convertMap wins"
  }
}

object OverloadTest {
  // force conversion to String
  def printStr(str: String): Unit = {
    println(str)
  }

  def main(args: Array[String]): Unit = {
    import Conversions._
    printStr(Map("key" -> "value"))               // ok: got "convertMap wins"
    printStr(Map("key" -> "value").map(identity)) // expect "convertMap wins", but got "convertIterable1 wins"
  }
}

Problem

  • Map#map has 2 alternatives: map[K2, V2](f: ((K, V)) => (K2, V2)): Map[K2, V2] and map[B](f: ((K, V)) => B): Iterable[B]. The first one is more specific so I expect Map("key" -> "value").map(identity) to return a Map, not an Iterable
  • It works as expected when we replace convertIterable1 with convertIterable2
  • This doesn't happen on Scala 3.3.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixed in Scala 3This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)infer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions