diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index a73bd0841957..d2eae4a6c72b 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -360,13 +360,13 @@ object PatternMatcher { .map(ref(unappResult).select(_)) matchArgsPlan(selectors, args, onSuccess) } + else if (isUnapplySeq && unapplySeqTypeElemTp(unapp.tpe.widen.finalResultType).exists) { + unapplySeqPlan(unappResult, args) + } else if (isUnapplySeq && isProductSeqMatch(unapp.tpe.widen, args.length, unapp.srcPos)) { val arity = productArity(unapp.tpe.widen, unapp.srcPos) unapplyProductSeqPlan(unappResult, args, arity) } - else if (isUnapplySeq && unapplySeqTypeElemTp(unapp.tpe.widen.finalResultType).exists) { - unapplySeqPlan(unappResult, args) - } else if unappResult.info <:< defn.NonEmptyTupleTypeRef then val components = (0 until foldApplyTupleType(unappResult.denot.info).length).toList.map(tupleApp(_, ref(unappResult))) matchArgsPlan(components, args, onSuccess) diff --git a/tests/pos/i19221.orig.scala b/tests/pos/i19221.orig.scala new file mode 100644 index 000000000000..7ce5267e3701 --- /dev/null +++ b/tests/pos/i19221.orig.scala @@ -0,0 +1,17 @@ +object Test: + class Custom extends scala.Product1[String]: + def length: Int = ??? + def apply(i: Int): Boolean = ??? + def drop(n: Int): scala.Seq[Boolean] = ??? + def toSeq: scala.Seq[Boolean] = ??? + + def canEqual(that: Any): Boolean = ??? + + val _1: String = ??? + val _2: String = ??? + val _3: Seq[String] = ??? + + object A: + def unapplySeq(i: Int): Custom = ??? + + val A(a, rest*) = 1 diff --git a/tests/pos/i19221.scala b/tests/pos/i19221.scala new file mode 100644 index 000000000000..8fd017bb803a --- /dev/null +++ b/tests/pos/i19221.scala @@ -0,0 +1,35 @@ +class T1 + +class P1 +final class P2 +class P3 + +class E1 +class E2 extends E1 +class E3 extends E1 + +object VarExt: + def unapplySeq(t1: T1): U1 = new U1 + +class U1 extends Product1[P1]: + def canEqual(that: Any): Boolean = ??? + + val _1: P1 = new P1 + val _2: P2 = new P2 + val _3: Seq[P3] = Seq(new P3) + + def length: Int = ??? + def apply(i: Int): E1 = ??? + def drop(n: Int): Seq[E2] = ??? + def toSeq: Seq[E3] = ??? + +class Test: + def m1(t1: T1): Unit = t1 match + case VarExt(c1, cs*) => // CCE: class P1 cannot be cast to class E1 + val e1: E1 = c1 + val e1s: Seq[E1] = cs + +object Main: + def main(args: Array[String]): Unit = + new Test().m1(new T1) +