@@ -235,8 +235,8 @@ object PatternMatcher {
235235 case _ =>
236236 tree.tpe
237237
238- /** Plan for matching `selectors ` against argument patterns `args` */
239- def matchArgsPlan (selectors : List [Tree ], args : List [Tree ], onSuccess : Plan ): Plan = {
238+ /** Plan for matching `components ` against argument patterns `args` */
239+ def matchArgsPlan (components : List [Tree ], args : List [Tree ], onSuccess : Plan ): Plan = {
240240 /* For a case with arguments that have some test on them such as
241241 * ```
242242 * case Foo(1, 2) => someCode
@@ -253,9 +253,9 @@ object PatternMatcher {
253253 * } else ()
254254 * ```
255255 */
256- def matchArgsSelectorsPlan ( selectors : List [Tree ], syms : List [Symbol ]): Plan =
257- selectors match {
258- case selector :: selectors1 => letAbstract(selector, selector .avoidPatBoundType())(sym => matchArgsSelectorsPlan(selectors1 , sym :: syms))
256+ def matchArgsComponentsPlan ( components : List [Tree ], syms : List [Symbol ]): Plan =
257+ components match {
258+ case component :: components1 => letAbstract(component, component .avoidPatBoundType())(sym => matchArgsComponentsPlan(components1 , sym :: syms))
259259 case Nil => matchArgsPatternPlan(args, syms.reverse)
260260 }
261261 def matchArgsPatternPlan (args : List [Tree ], syms : List [Symbol ]): Plan =
@@ -267,7 +267,7 @@ object PatternMatcher {
267267 assert(syms.isEmpty)
268268 onSuccess
269269 }
270- matchArgsSelectorsPlan(selectors , Nil )
270+ matchArgsComponentsPlan(components , Nil )
271271 }
272272
273273 /** Plan for matching the sequence in `seqSym` against sequence elements `args`.
@@ -330,7 +330,15 @@ object PatternMatcher {
330330 sym.isAllOf(SyntheticCase ) && sym.owner.is(Scala2x )
331331
332332 if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length)
333- matchArgsPlan(caseAccessors.map(ref(scrutinee).select(_)), args, onSuccess)
333+ def tupleSel (sym : Symbol ) = ref(scrutinee).select(sym)
334+ def tupleApp (i : Int ) = // manually inlining the call to NonEmptyTuple#apply, because it's an inline method
335+ ref(defn.RuntimeTuplesModule )
336+ .select(defn.RuntimeTuples_apply )
337+ .appliedTo(ref(scrutinee), Literal (Constant (i)))
338+ .cast(args(i).tpe.widen)
339+ val isGenericTuple = defn.isTupleClass(caseClass) && ! defn.isTupleNType(tree.tpe)
340+ val components = if isGenericTuple then caseAccessors.indices.toList.map(tupleApp) else caseAccessors.map(tupleSel)
341+ matchArgsPlan(components, args, onSuccess)
334342 else if (unapp.tpe <:< (defn.BooleanType ))
335343 TestPlan (GuardTest , unapp, unapp.span, onSuccess)
336344 else
0 commit comments