Open
Description
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]
andmap[B](f: ((K, V)) => B): Iterable[B]
. The first one is more specific so I expectMap("key" -> "value").map(identity)
to return aMap
, not anIterable
- It works as expected when we replace
convertIterable1
withconvertIterable2
- This doesn't happen on Scala 3.3.5