@@ -231,8 +231,8 @@ object PatternMatcher {
231
231
case _ =>
232
232
tree.tpe
233
233
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 = {
236
236
/* For a case with arguments that have some test on them such as
237
237
* ```
238
238
* case Foo(1, 2) => someCode
@@ -249,9 +249,9 @@ object PatternMatcher {
249
249
* } else ()
250
250
* ```
251
251
*/
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))
255
255
case Nil => matchArgsPatternPlan(args, syms.reverse)
256
256
}
257
257
def matchArgsPatternPlan (args : List [Tree ], syms : List [Symbol ]): Plan =
@@ -263,7 +263,7 @@ object PatternMatcher {
263
263
assert(syms.isEmpty)
264
264
onSuccess
265
265
}
266
- matchArgsSelectorsPlan(selectors , Nil )
266
+ matchArgsComponentsPlan(components , Nil )
267
267
}
268
268
269
269
/** Plan for matching the sequence in `seqSym` against sequence elements `args`.
@@ -326,7 +326,15 @@ object PatternMatcher {
326
326
sym.isAllOf(SyntheticCase ) && sym.owner.is(Scala2x )
327
327
328
328
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)
330
338
else if (unapp.tpe <:< (defn.BooleanType ))
331
339
TestPlan (GuardTest , unapp, unapp.span, onSuccess)
332
340
else
0 commit comments