scala / scala3

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

Scala 2 regression: extension method is not searched in the companion object of a type parameter's parameter #21951

Open neko-kai opened 1 week ago

neko-kai commented 1 week ago

Compiler version

3.5.2, 3.3.4

Minimized code

Scala 3 Scastie (error): https://scastie.scala-lang.org/yl3UgZcSSKmowV8owgjtzg Scala 2 Scastie (works correctly): https://scastie.scala-lang.org/cPFPUhfCQ4ONHzBIKawgbg

final case class X(val i: Int)
object X {
  implicit final class XOps[F[_]](xs: F[X]) {
    def unpack(implicit ev: F[X] <:< Iterable[X]): Iterable[Int] = xs.map(_.i)
  }
}

object App extends App {
  // good
  val ys: List[X] = List(X(1))
  println(ys.unpack)

  // bad
  def printPolymorphic[F[_]](xs: F[X])(implicit ev: F[X] <:< Iterable[X]) = {
    locally {
      // implicit XOps is correct
      import X.XOps
      println(xs.unpack) // found
    }
    // but it's not being searched for in the companion object of X
    println(xs.unpack) // error: unpack is not a member of F[X]
  }
  printPolymorphic[List](ys)
}

Output

value unpack is not a member of F[X]

where:    F is a type in method printPolymorphic with bounds <: [_] =>> Any

Expectation

Expected to work correctly, as in Scala 2. When xs has a concrete type constructor List in List[X], the extension method is correctly searched in the companion of X. However, the X companion is incorrectly omitted from search when xs has an abstract type parameter type constructor F in F[X].