@@ -231,8 +231,8 @@ object PatternMatcher {
231231 case _ =>
232232 tree.tpe
233233
234- /** Plan for matching `selectors ` against argument patterns `args` */
235- def matchArgsPlan (selectors : List [Tree ], args : List [Tree ], onSuccess : Plan ): Plan = {
234+ /** Plan for matching `components ` against argument patterns `args` */
235+ def matchArgsPlan (components : List [Tree ], args : List [Tree ], onSuccess : Plan ): Plan = {
236236 /* For a case with arguments that have some test on them such as
237237 * ```
238238 * case Foo(1, 2) => someCode
@@ -249,9 +249,9 @@ object PatternMatcher {
249249 * } else ()
250250 * ```
251251 */
252- def matchArgsSelectorsPlan ( selectors : List [Tree ], syms : List [Symbol ]): Plan =
253- selectors match {
254- case selector :: selectors1 => letAbstract(selector, selector .avoidPatBoundType())(sym => matchArgsSelectorsPlan(selectors1 , sym :: syms))
252+ def matchArgsComponentsPlan ( components : List [Tree ], syms : List [Symbol ]): Plan =
253+ components match {
254+ case component :: components1 => letAbstract(component, component .avoidPatBoundType())(sym => matchArgsComponentsPlan(components1 , sym :: syms))
255255 case Nil => matchArgsPatternPlan(args, syms.reverse)
256256 }
257257 def matchArgsPatternPlan (args : List [Tree ], syms : List [Symbol ]): Plan =
@@ -263,7 +263,7 @@ object PatternMatcher {
263263 assert(syms.isEmpty)
264264 onSuccess
265265 }
266- matchArgsSelectorsPlan(selectors , Nil )
266+ matchArgsComponentsPlan(components , Nil )
267267 }
268268
269269 /** Plan for matching the sequence in `seqSym` against sequence elements `args`.
@@ -326,7 +326,15 @@ object PatternMatcher {
326326 sym.isAllOf(SyntheticCase ) && sym.owner.is(Scala2x )
327327
328328 if (isSyntheticScala2Unapply(unapp.symbol) && caseAccessors.length == args.length)
329- matchArgsPlan(caseAccessors.map(ref(scrutinee).select(_)), args, onSuccess)
329+ def tupleSel (sym : Symbol ) = ref(scrutinee).select(sym)
330+ def tupleApp (i : Int ) = // manually inlining the call to NonEmptyTuple#apply, because it's an inline method
331+ ref(defn.RuntimeTuplesModule )
332+ .select(defn.RuntimeTuples_apply )
333+ .appliedTo(ref(scrutinee), Literal (Constant (i)))
334+ .cast(args(i).tpe.widen)
335+ val isGenericTuple = defn.isTupleClass(caseClass) && ! defn.isTupleNType(tree.tpe)
336+ val components = if isGenericTuple then caseAccessors.indices.toList.map(tupleApp) else caseAccessors.map(tupleSel)
337+ matchArgsPlan(components, args, onSuccess)
330338 else if (unapp.tpe <:< (defn.BooleanType ))
331339 TestPlan (GuardTest , unapp, unapp.span, onSuccess)
332340 else
0 commit comments