Skip to content

Interaction of partial unification and GADT pattern matching #10292

Open
@TomasMikula

Description

@TomasMikula

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:

  1. Foo is a GADT. Changing Bar to

    case class Bar[F[_], A](fa: F[Int]) extends Foo[F, A]

    is sufficient to make it compile.

  2. A is a type parameter of f. Pulling it out, as in

    object 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.

  3. Partial unification is involved on the type of parameter foo. Changing f to

    def f[F[_], B](foo: Foo[F, B]): Unit = foo match {
      case Bar(_) => ()
    }

    is sufficient to make it compile.

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/)gadtpatmat

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions