Open
Description
To reproduce, try to compile the following snippet by scalac 2.12.2 with -Ypartial-unification
.
import scala.language.higherKinds
sealed abstract class Foo[F[_], A]
case class Bar[F[_]](fa: F[Int]) extends Foo[F, Unit]
class Fun[A, B]
object Main {
def f[A, B](foo: Foo[({ type λ[b] = Fun[A, b] })#λ, B]): Unit = foo match {
case Bar(_) => ()
}
}
It results in
main.scala:11: error: constructor of type Bar[F] cannot be uniquely instantiated to expected type Foo[[b]Fun[?,b],?]
--- because ---
undetermined type
case Bar(_) => ()
^
Note that all of these three aspects are necessary to reproduce the bug:
-
Foo
is a GADT. ChangingBar
tocase class Bar[F[_], A](fa: F[Int]) extends Foo[F, A]
is sufficient to make it compile.
-
A
is a type parameter off
. Pulling it out, as inobject Main { class A def f[B](foo: Foo[({ type λ[b] = Fun[A, b] })#λ, B]): Unit = foo match { case Bar(_) => () } }
or in
class Main[A] { def f[B](foo: Foo[({ type λ[b] = Fun[A, b] })#λ, B]): Unit = foo match { case Bar(_) => () } }
is sufficient to make it compile.
-
Partial unification is involved on the type of parameter
foo
. Changingf
todef f[F[_], B](foo: Foo[F, B]): Unit = foo match { case Bar(_) => () }
is sufficient to make it compile.