From b222e9f91a37b672d455fd5227638900229bba3e Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Sun, 11 Nov 2018 20:03:53 +0100 Subject: [PATCH] Fix #5422: prefer type tp1 in Typ(tp1) - Prod(tp2, ...) In `Typ(tp1) - Prod(tp2, ...)` with `tp1 <: tp2`, we rewrite `Typ(tp1)` to `Prod(tpx, Nil)`. We should prefer `tp1` over `tp2`, as the latter is usually a bigger space, due to the erasure of pattern bound symbol references during pattern-space projection. --- .../tools/dotc/transform/patmat/Space.scala | 2 +- tests/patmat/i5422.scala | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/patmat/i5422.scala diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 1b6834ed831f..bf58b204d575 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -243,7 +243,7 @@ trait SpaceLogic { else a case (Typ(tp1, _), Prod(tp2, fun, sym, ss, true)) => // rationale: every instance of `tp1` is covered by `tp2(_)` - if (isSubType(tp1, tp2)) minus(Prod(tp2, fun, sym, signature(fun, sym, ss.length).map(Typ(_, false)), true), b) + if (isSubType(tp1, tp2)) minus(Prod(tp1, fun, sym, signature(fun, sym, ss.length).map(Typ(_, false)), true), b) else if (canDecompose(tp1)) tryDecompose1(tp1) else a case (_, Or(ss)) => diff --git a/tests/patmat/i5422.scala b/tests/patmat/i5422.scala new file mode 100644 index 000000000000..c40b71c0eb79 --- /dev/null +++ b/tests/patmat/i5422.scala @@ -0,0 +1,21 @@ +import scala.language.higherKinds + +object Test { + + trait X + case object Y extends X + + sealed trait Foo[F[_], O] { + def bar: Foo[F, O] = this match { + case Qux(fa, f) => qux(fa) { + case Left(Y) => ??? + case x => ??? + } + } + } + + case class Qux[F[_], A, O](fa: F[A], f: Either[X, A] => Int) extends Foo[F, O] + + def qux[F[_], A, O](fa: F[A])(f: Either[X, A] => Int): Foo[F, O] = + Qux(fa, f) +}