Skip to content

Commit 8639793

Browse files
committed
fix #3182: return correct signatures for extractors
1 parent 2b9d346 commit 8639793

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -451,30 +451,36 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
451451
/** Parameter types of the case class type `tp`. Adapted from `unapplyPlan` in patternMatcher */
452452
def signature(unapp: Type, unappSym: Symbol, argLen: Int): List[Type] = {
453453
def caseClass = unappSym.owner.linkedClass
454+
454455
lazy val caseAccessors = caseClass.caseAccessors.filter(_.is(Method))
455456

456457
def isSyntheticScala2Unapply(sym: Symbol) =
457458
sym.is(SyntheticCase) && sym.owner.is(Scala2x)
458459

459-
val mt @ MethodType(_) = unapp.widen
460+
val mt@MethodType(_) = unapp.widen
460461

461-
if (isSyntheticScala2Unapply(unappSym) && caseAccessors.length == argLen)
462-
caseAccessors.map(_.info.asSeenFrom(mt.paramInfos.head, caseClass).widen)
463-
else if (mt.resultType.isRef(defn.BooleanClass))
464-
List()
465-
else {
466-
val isUnapplySeq = unappSym.name == nme.unapplySeq
467-
if (isProductMatch(mt.resultType, argLen) && !isUnapplySeq) {
468-
productSelectors(mt.resultType).take(argLen)
469-
.map(_.info.asSeenFrom(mt.resultType, mt.resultType.classSymbol).widen)
470-
}
462+
val sig =
463+
if (isSyntheticScala2Unapply(unappSym) && caseAccessors.length == argLen)
464+
caseAccessors.map(_.info.asSeenFrom(mt.paramInfos.head, caseClass).widen)
465+
else if (mt.resultType.isRef(defn.BooleanClass))
466+
List()
471467
else {
472-
val resTp = mt.resultType.select(nme.get).resultType.widen
473-
if (isUnapplySeq) scalaListType.appliedTo(resTp.argTypes.head) :: Nil
474-
else if (argLen == 0) Nil
475-
else productSelectors(resTp).map(_.info.asSeenFrom(resTp, resTp.classSymbol).widen)
468+
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)
472+
}
473+
else {
474+
val resTp = mt.resultType.select(nme.get).resultType.widen
475+
if (isUnapplySeq) scalaListType.appliedTo(resTp.argTypes.head) :: Nil
476+
else if (argLen == 0) Nil
477+
else resTp :: Nil
478+
}
476479
}
477-
}
480+
481+
debug.println(s"signature of ${unappSym.showFullName} ----> ${sig.map(_.show).mkString(", ")}")
482+
483+
sig
478484
}
479485

480486
/** Decompose a type into subspaces -- assume the type can be decomposed */

tests/patmat/t10502.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
5: Pattern Match Exhaustivity: Option(None)
2+
15: Pattern Match Exhaustivity: Nil

tests/patmat/t10502.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
object Perhaps {
2+
3+
def unapply[A](oa: Option[A]): Some[Option[A]] = Some(oa)
4+
5+
Option("hello") match {
6+
case Perhaps(Some(s)) => println(s)
7+
}
8+
9+
List(Option("hello")) match {
10+
case Perhaps(Some(s)) :: t => println(s)
11+
case Perhaps(None ) :: t => ()
12+
case Nil => ()
13+
}
14+
15+
List(Option("hello")) match {
16+
case Perhaps(Some(s)) :: t => println(s)
17+
case Perhaps(None ) :: t => ()
18+
// case Nil => ()
19+
}
20+
}

0 commit comments

Comments
 (0)