Skip to content

Typechecking regression involving pattern matching on a nested class type-parameterized by a member type of a given #16997

Closed
@TomasMikula

Description

@TomasMikula

Compiler version

3.3.1-RC1-bin-20230221-847eccc-NIGHTLY

(Works in 3.2.2, 3.3.0-RC3, so this is a regression.)

Code to reproduce

I apologize that this code is not as minimal as it could be.

class Funs {
  sealed trait ->[A, B]
}

/**
 * Binary tree with leafs holding values of types `F[X]`, `F[Y]`, ...
 * The complete structure of the tree is expressed by the type `A`, using the tags for branches and leafs.
 *
 * @tparam <*> tag for branches
 * @tparam T tag for leafs.
 * @tparam F value type of leafs. Each leaf holds a value of type `F[T]`, for some type `T`.
 * @tparam A captures the complete structure of the tree
 */
enum Tree[<*>[_, _], T[_], F[_], A] {
  case Branch[<*>[_, _], T[_], F[_], A, B](
    l: Tree[<*>, T, F, A],
    r: Tree[<*>, T, F, B],
  ) extends Tree[<*>, T, F, A <*> B]

  case Leaf[<*>[_, _], T[_], F[_], A](
    value: F[A],
  ) extends Tree[<*>, T, F, T[A]]

  def <*>[B](that: Tree[<*>, T, F, B]): Tree[<*>, T, F, A <*> B] =
    Branch(this, that)

  def partition[G[_], H[_]](
    f: [x] => F[x] => Either[G[x], H[x]],
  )(using
    funs: Funs,
  ): Partitioned[G, H, funs.->] =
    this match {
      case Leaf(a) =>
        f(a) match
          case Left(a)  => Partitioned.Left(Leaf(a))
          case Right(a) => Partitioned.Right(Leaf(a))
      case Branch(l, r) =>
        import Partitioned.{Both, Left, Right}
        import l.Partitioned.{Both => LBoth, Left => LLeft, Right => LRight}
        import r.Partitioned.{Both => RBoth, Left => RLeft, Right => RRight}

        (l.partition(f), r.partition(f)) match
          case (LLeft(lg),     RLeft(rg))     => Left(lg <*> rg)
          case (LLeft(lg),     RRight(rh))    => Both(lg, rh)
          case (LLeft(lg),     RBoth(rg, rh)) => Both(lg <*> rg, rh)
          case (LRight(lh),    RLeft(rg))     => Both(rg, lh)
          case (LRight(lh),    RRight(rh))    => Right(lh <*> rh)
          case (LRight(lh),    RBoth(rg, rh)) => Both(rg, lh <*> rh)
          case (LBoth(lg, lh), RLeft(rg))     => Both(lg <*> rg, lh)
          case (LBoth(lg, lh), RRight(rh))    => Both(lg, lh <*> rh)
          case (LBoth(lg, lh), RBoth(rg, rh)) => Both(lg <*> rg, lh <*> rh)
    }

  // note that `->` is never even used, to keep this reproduction case small
  enum Partitioned[G[_], H[_], ->[_, _]] {
    case Left(value: Tree[<*>, T, G, A])
    case Right(value: Tree[<*>, T, H, A])
    case Both[G[_], H[_], X, Y, ->[_, _]](
      l: Tree[<*>, T, G, X],
      r: Tree[<*>, T, H, Y],
    ) extends Partitioned[G, H, ->]
  }
}

Output

Click to expand
% sbt compile
[info] welcome to sbt 1.8.2 (AdoptOpenJDK Java 16)
[info] loading global plugins from /Users/thomas/.sbt/1.0/plugins
[info] loading project definition from /Users/thomas/tmp/dotty-playground/pattern-matching-regression/project
[info] loading settings for project pattern-matching-regression from build.sbt ...
[info] set current project to pattern-matching-regression (in build file:/Users/thomas/tmp/dotty-playground/pattern-matching-regression/)
[info] Executing in batch mode. For better performance use sbt's shell
[info] compiling 1 Scala source to /Users/thomas/tmp/dotty-playground/pattern-matching-regression/target/scala-3.3.1-RC1-bin-20230221-847eccc-NIGHTLY/classes ...
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:43:61 
[error] 43 |          case (LLeft(lg),     RLeft(rg))     => Left(lg <*> rg)
[error]    |                                                             ^^
[error]    |  Found:    (rg : Tree[<*>, T, G$2, B$1])
[error]    |  Required: Tree[<*>, T, G$1, B]
[error]    |
[error]    |  where:    <*> is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |            B   is a type variable
[error]    |            G$1 is a type in method partition with bounds <: [_] =>> Any
[error]    |            G$2 is a type in method partition with bounds <: [_] =>> Any
[error]    |            T   is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:44:54 
[error] 44 |          case (LLeft(lg),     RRight(rh))    => Both(lg, rh)
[error]    |                                                      ^^
[error]    |  Found:    (lg : Tree[<*>, T, G$3, A$2])
[error]    |  Required: Tree[<*>, T, G, X]
[error]    |
[error]    |  where:    <*> is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |            G   is a type in method partition with bounds <: [_] =>> Any
[error]    |            G$3 is a type in method partition with bounds <: [_] =>> Any
[error]    |            T   is a type in class Tree with bounds <: [_] =>> Any
[error]    |            X   is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:44:58 
[error] 44 |          case (LLeft(lg),     RRight(rh))    => Both(lg, rh)
[error]    |                                                          ^^
[error]    |  Found:    (rh : Tree[<*>, T, H$4, B$1])
[error]    |  Required: Tree[<*>, T, H, Y]
[error]    |
[error]    |  where:    <*> is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |            H   is a type in method partition with bounds <: [_] =>> Any
[error]    |            H$4 is a type in method partition with bounds <: [_] =>> Any
[error]    |            T   is a type in class Tree with bounds <: [_] =>> Any
[error]    |            Y   is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:45:61 
[error] 45 |          case (LLeft(lg),     RBoth(rg, rh)) => Both(lg <*> rg, rh)
[error]    |                                                             ^^
[error]    |  Found:    (rg : Tree[<*>, T, G$6, X$1])
[error]    |  Required: Tree[<*>, T, G$5, B]
[error]    |
[error]    |  where:    <*> is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |            B   is a type variable
[error]    |            G$5 is a type in method partition with bounds <: [_] =>> Any
[error]    |            G$6 is a type in method partition with bounds <: [_] =>> Any
[error]    |            T   is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:45:65 
[error] 45 |          case (LLeft(lg),     RBoth(rg, rh)) => Both(lg <*> rg, rh)
[error]    |                                                                 ^^
[error]    |  Found:    (rh : Tree[<*>, T, H$6, Y$1])
[error]    |  Required: Tree[<*>, T, H, Y]
[error]    |
[error]    |  where:    <*> is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |            H   is a type in method partition with bounds <: [_] =>> Any
[error]    |            H$6 is a type in method partition with bounds <: [_] =>> Any
[error]    |            T   is a type in class Tree with bounds <: [_] =>> Any
[error]    |            Y   is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:46:54 
[error] 46 |          case (LRight(lh),    RLeft(rg))     => Both(rg, lh)
[error]    |                                                      ^^
[error]    |  Found:    (rg : Tree[<*>, T, G$8, B$1])
[error]    |  Required: Tree[<*>, T, G, X]
[error]    |
[error]    |  where:    <*> is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |            G   is a type in method partition with bounds <: [_] =>> Any
[error]    |            G$8 is a type in method partition with bounds <: [_] =>> Any
[error]    |            T   is a type in class Tree with bounds <: [_] =>> Any
[error]    |            X   is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:46:58 
[error] 46 |          case (LRight(lh),    RLeft(rg))     => Both(rg, lh)
[error]    |                                                          ^^
[error]    |  Found:    (lh : Tree[<*>, T, H$7, A$2])
[error]    |  Required: Tree[<*>, T, H, Y]
[error]    |
[error]    |  where:    <*> is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |            H   is a type in method partition with bounds <: [_] =>> Any
[error]    |            H$7 is a type in method partition with bounds <: [_] =>> Any
[error]    |            T   is a type in class Tree with bounds <: [_] =>> Any
[error]    |            Y   is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:47:62 
[error] 47 |          case (LRight(lh),    RRight(rh))    => Right(lh <*> rh)
[error]    |                                                              ^^
[error]    | Found:    (rh : Tree[<*>, T, H$10, B$1])
[error]    | Required: Tree[<*>, T, H$9, B]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           B    is a type variable
[error]    |           H$10 is a type in method partition with bounds <: [_] =>> Any
[error]    |           H$9  is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:48:54 
[error] 48 |          case (LRight(lh),    RBoth(rg, rh)) => Both(rg, lh <*> rh)
[error]    |                                                      ^^
[error]    | Found:    (rg : Tree[<*>, T, G$12, X$2])
[error]    | Required: Tree[<*>, T, G, X]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           G    is a type in method partition with bounds <: [_] =>> Any
[error]    |           G$12 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |           X    is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:48:65 
[error] 48 |          case (LRight(lh),    RBoth(rg, rh)) => Both(rg, lh <*> rh)
[error]    |                                                                 ^^
[error]    | Found:    (rh : Tree[<*>, T, H$12, Y$2])
[error]    | Required: Tree[<*>, T, H$11, B]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           B    is a type variable
[error]    |           H$11 is a type in method partition with bounds <: [_] =>> Any
[error]    |           H$12 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:49:61 
[error] 49 |          case (LBoth(lg, lh), RLeft(rg))     => Both(lg <*> rg, lh)
[error]    |                                                             ^^
[error]    | Found:    (rg : Tree[<*>, T, G$14, B$1])
[error]    | Required: Tree[<*>, T, G$13, B]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           B    is a type variable
[error]    |           G$13 is a type in method partition with bounds <: [_] =>> Any
[error]    |           G$14 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:49:65 
[error] 49 |          case (LBoth(lg, lh), RLeft(rg))     => Both(lg <*> rg, lh)
[error]    |                                                                 ^^
[error]    | Found:    (lh : Tree[<*>, T, H$13, Y$3])
[error]    | Required: Tree[<*>, T, H, Y]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           H    is a type in method partition with bounds <: [_] =>> Any
[error]    |           H$13 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |           Y    is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:50:54 
[error] 50 |          case (LBoth(lg, lh), RRight(rh))    => Both(lg, lh <*> rh)
[error]    |                                                      ^^
[error]    | Found:    (lg : Tree[<*>, T, G$15, X$4])
[error]    | Required: Tree[<*>, T, G, X]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           G    is a type in method partition with bounds <: [_] =>> Any
[error]    |           G$15 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |           X    is a type variable
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:50:65 
[error] 50 |          case (LBoth(lg, lh), RRight(rh))    => Both(lg, lh <*> rh)
[error]    |                                                                 ^^
[error]    | Found:    (rh : Tree[<*>, T, H$16, B$1])
[error]    | Required: Tree[<*>, T, H$15, B]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           B    is a type variable
[error]    |           H$15 is a type in method partition with bounds <: [_] =>> Any
[error]    |           H$16 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:51:61 
[error] 51 |          case (LBoth(lg, lh), RBoth(rg, rh)) => Both(lg <*> rg, lh <*> rh)
[error]    |                                                             ^^
[error]    | Found:    (rg : Tree[<*>, T, G$18, X$6])
[error]    | Required: Tree[<*>, T, G$17, B]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           B    is a type variable
[error]    |           G$17 is a type in method partition with bounds <: [_] =>> Any
[error]    |           G$18 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] -- [E007] Type Mismatch Error: /Users/thomas/tmp/dotty-playground/pattern-matching-regression/test.scala:51:72 
[error] 51 |          case (LBoth(lg, lh), RBoth(rg, rh)) => Both(lg <*> rg, lh <*> rh)
[error]    |                                                                        ^^
[error]    | Found:    (rh : Tree[<*>, T, H$18, Y$6])
[error]    | Required: Tree[<*>, T, H$17, B]
[error]    |
[error]    | where:    <*>  is a type in class Tree with bounds <: [_, _] =>> Any
[error]    |           B    is a type variable
[error]    |           H$17 is a type in method partition with bounds <: [_] =>> Any
[error]    |           H$18 is a type in method partition with bounds <: [_] =>> Any
[error]    |           T    is a type in class Tree with bounds <: [_] =>> Any
[error]    |
[error]    | longer explanation available when compiling with `-explain`
[error] 16 errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 10 s, completed Feb 22, 2023, 7:23:17 PM

Expectation

The code should compile, as was the case with Scala 3.2.2.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions