@@ -377,8 +377,9 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
377
377
/* Whether the extractor is irrefutable */
378
378
def irrefutable (unapp : tpd.Tree ): Boolean = {
379
379
// TODO: optionless patmat
380
- unapp.tpe.widen.resultType.isRef(scalaSomeClass) ||
381
- (unapp.symbol.is(Synthetic ) && unapp.symbol.owner.linkedClass.is(Case ))
380
+ unapp.tpe.widen.finalResultType.isRef(scalaSomeClass) ||
381
+ (unapp.symbol.is(Synthetic ) && unapp.symbol.owner.linkedClass.is(Case )) ||
382
+ productArity(unapp.tpe.widen.finalResultType) > 0
382
383
}
383
384
384
385
/** Return the space that represents the pattern `pat`
@@ -457,21 +458,31 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
457
458
def isSyntheticScala2Unapply (sym : Symbol ) =
458
459
sym.is(SyntheticCase ) && sym.owner.is(Scala2x )
459
460
460
- val mt @ MethodType (_) = unapp.widen
461
+ val mt @ MethodType (_) = unapp.widen
462
+
463
+ // Case unapply:
464
+ // 1. return types of constructor fields if the extractor is synthesized for Scala2 case classes & length match
465
+ // 2. return Nil if unapply returns Boolean (boolean pattern)
466
+ // 3. return product selector types if unapply returns a product type (product pattern)
467
+ // 4. return product selectors of `T` where `def get: T` is a member of the return type of unapply & length match (named-based pattern)
468
+ // 5. otherwise, return `T` where `def get: T` is a member of the return type of unapply
469
+ //
470
+ // Case unapplySeq:
471
+ // 1. return the type `List[T]` where `T` is the element type of the unapplySeq return type `Seq[T]`
461
472
462
473
val sig =
463
474
if (isSyntheticScala2Unapply(unappSym) && caseAccessors.length == argLen)
464
475
caseAccessors.map(_.info.asSeenFrom(mt.paramInfos.head, caseClass).widen)
465
- else if (mt.resultType .isRef(defn.BooleanClass ))
476
+ else if (mt.finalResultType .isRef(defn.BooleanClass ))
466
477
List ()
467
478
else {
468
479
val isUnapplySeq = unappSym.name == nme.unapplySeq
469
- if (isProductMatch(mt.resultType , argLen) && ! isUnapplySeq) {
470
- productSelectors(mt.resultType ).take(argLen)
471
- .map(_.info.asSeenFrom(mt.resultType , mt.resultType.classSymbol).widen)
480
+ if (isProductMatch(mt.finalResultType , argLen) && ! isUnapplySeq) {
481
+ productSelectors(mt.finalResultType ).take(argLen)
482
+ .map(_.info.asSeenFrom(mt.finalResultType , mt.resultType.classSymbol).widen)
472
483
}
473
484
else {
474
- val resTp = mt.resultType .select(nme.get).resultType .widen
485
+ val resTp = mt.finalResultType .select(nme.get).finalResultType .widen
475
486
if (isUnapplySeq) scalaListType.appliedTo(resTp.argTypes.head) :: Nil
476
487
else if (argLen == 0 ) Nil
477
488
else if (isProductMatch(resTp, argLen))
0 commit comments