From e0bd31dab6a119978cf0baa14ae3d6714e43dc67 Mon Sep 17 00:00:00 2001 From: EnzeXing Date: Sat, 5 Jul 2025 20:54:59 -0400 Subject: [PATCH] fix error in product-sequence match --- .../tools/dotc/transform/init/Objects.scala | 3 ++ .../unapplySeq-product-sequence-match.scala | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/init-global/pos/unapplySeq-product-sequence-match.scala diff --git a/compiler/src/dotty/tools/dotc/transform/init/Objects.scala b/compiler/src/dotty/tools/dotc/transform/init/Objects.scala index dfa685f8aaa9..92262d528487 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Objects.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Objects.scala @@ -1804,6 +1804,9 @@ class Objects(using Context @constructorOnly): val seqPats = pats.drop(selectors.length - 1) val toSeqRes = call(resToMatch, selectors.last, Nil, resultTp, superType = NoType, needResolve = true) val toSeqResTp = resultTp.memberInfo(selectors.last).finalResultType + elemTp = unapplySeqTypeElemTp(toSeqResTp) + // elemTp must conform to the signature in sequence match + assert(elemTp.exists, "Product sequence match fails on " + pat + " since last element type of product is " + toSeqResTp) evalSeqPatterns(toSeqRes, toSeqResTp, elemTp, seqPats) end if // TODO: refactor the code of product sequence match, avoid passing NoType to parameter elemTp in evalSeqPatterns diff --git a/tests/init-global/pos/unapplySeq-product-sequence-match.scala b/tests/init-global/pos/unapplySeq-product-sequence-match.scala new file mode 100644 index 000000000000..2105fb63dc6e --- /dev/null +++ b/tests/init-global/pos/unapplySeq-product-sequence-match.scala @@ -0,0 +1,29 @@ +trait Node { + val prefix = 5 + val child = Array(3) +} + +class SpecialNode extends Node + +class Group extends Node + +class C extends Node + +object Elem { + def apply(prefix: Int, children: Int*) = new C + def unapplySeq(n: Node) = n match { + case _: SpecialNode | _: Group => None + case _ => Some((n.prefix, n.child.toSeq)) + } +} + +object O { + def updateNode(node: Node): Node = + node match { + case Elem(prefix, children @ _*) => + Elem(prefix, children*) + case other => other + } + + val a = updateNode(new Group) +}