Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
TomasMikula opened this issue Feb 22, 2023 · 2 comments · Fixed by #17025
Assignees
Labels
area:infer area:typer itype:bug regression This worked in a previous version but doesn't anymore
Milestone

Comments

@TomasMikula
Copy link
Contributor

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.

@smarter
Copy link
Member

smarter commented Feb 22, 2023

Regressed in 12a8051 /cc @dwijnand

@smarter smarter added area:typer regression This worked in a previous version but doesn't anymore and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Feb 22, 2023
@Kordyjan Kordyjan added this to the 3.3.0 backports milestone Feb 23, 2023
@Kordyjan Kordyjan modified the milestones: 3.3.0 backports, 3.3.1-RC1 Feb 27, 2023
@dwijnand dwijnand modified the milestones: 3.3.1-RC1, 3.3.0 backports Mar 2, 2023
@dwijnand
Copy link
Member

dwijnand commented Mar 2, 2023

Ah, no, we didn't backport #16786 for 3.3.0, so no need.

@dwijnand dwijnand modified the milestones: 3.3.0 backports, 3.3.1-RC1 Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:infer area:typer itype:bug regression This worked in a previous version but doesn't anymore
Projects
None yet
4 participants