Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,9 @@ object PatternMatcher {
*
* `getResult` is a product, where the last element is a sequence of elements.
*/
def unapplyProductSeqPlan(getResult: Symbol, args: List[Tree], arity: Int): Plan = {
def unapplyProductSeqPlan(selectors: List[Tree], args: List[Tree]): Plan = {
val arity = selectors.length
assert(arity <= args.size + 1)
val selectors = productSelectors(getResult.info).map(ref(getResult).select(_))

val matchSeq =
letAbstract(selectors.last) { seqResult =>
unapplySeqPlan(seqResult, args.drop(arity - 1))
Expand Down Expand Up @@ -415,8 +414,8 @@ object PatternMatcher {
else if isUnapplySeq && unapplySeqTypeElemTp(unappType.finalResultType).exists then
unapplySeqPlan(unappResult, args)
else if isUnapplySeq && isProductSeqMatch(unappType, args.length, unapp.srcPos) then
val arity = productArity(unappType, unapp.srcPos)
unapplyProductSeqPlan(unappResult, args, arity)
val selectors = productSelectors(unappType).map(ref(unappResult).select(_))
unapplyProductSeqPlan(selectors, args)
else if unappResult.info <:< defn.NonEmptyTupleTypeRef then
val components =
(0 until unappResult.denot.info.tupleElementTypes.getOrElse(Nil).length)
Expand All @@ -426,12 +425,20 @@ object PatternMatcher {
assert(isGetMatch(unappType))
val argsPlan = {
val get = getOfGetMatch(ref(unappResult))
val arity = productArity(get.tpe.stripNamedTuple, unapp.srcPos)
if (isUnapplySeq)
letAbstract(get) { getResult =>
if unapplySeqTypeElemTp(get.tpe).exists
then unapplySeqPlan(getResult, args)
else unapplyProductSeqPlan(getResult, args, arity)
if unapplySeqTypeElemTp(get.tpe).exists then
unapplySeqPlan(getResult, args)
else if isGenericTuple(getResult.info) then
val elemTypes = getResult.info.tupleElementTypes.getOrElse(Nil)
val selectors = elemTypes.zipWithIndex.map { (tp, i) =>
tupleApp(i, ref(getResult)).cast(tp)
}
unapplyProductSeqPlan(selectors, args)
else {
val selectors = productSelectors(getResult.info).map(ref(getResult).select(_))
unapplyProductSeqPlan(selectors, args)
}
}
else
letAbstract(get) { getResult =>
Expand Down
5 changes: 5 additions & 0 deletions tests/pos/i25663.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object Foo:
def unapplySeq(f: Int): Option[String *: Seq[Int] *: EmptyTuple] = ???

def foo(f: Int) = f match
case Foo(name, ns*) => ???
Loading