Skip to content

Commit

Permalink
Prioritise sequence-matches over product-sequence-matches (#19260)
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand authored Dec 15, 2023
2 parents fe55cef + 4b8e180 commit b1d1fe8
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions tests/pos/i19221.orig.scala
Original file line number Diff line number Diff line change
@@ -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
35 changes: 35 additions & 0 deletions tests/pos/i19221.scala
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit b1d1fe8

Please sign in to comment.