Skip to content

Commit ea64026

Browse files
authored
Merge pull request #10094 from dotty-staging/fix-10085
Fix #10085: check if enum case confirms to scrutinee type
2 parents e7a197c + 22cdeec commit ea64026

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,6 @@ object TypeOps:
633633
* returned. Otherwise, `NoType` is returned.
634634
*/
635635
def refineUsingParent(parent: Type, child: Symbol)(using Context): Type = {
636-
if (child.isTerm && child.is(Case, butNot = Module)) return child.termRef // enum vals always match
637-
638636
// <local child> is a place holder from Scalac, it is hopeless to instantiate it.
639637
//
640638
// Quote from scalac (from nsc/symtab/classfile/Pickler.scala):

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -527,15 +527,9 @@ class SpaceEngine(using Context) extends SpaceLogic {
527527
/** Parameter types of the case class type `tp`. Adapted from `unapplyPlan` in patternMatcher */
528528
def signature(unapp: TermRef, scrutineeTp: Type, argLen: Int): List[Type] = {
529529
val unappSym = unapp.symbol
530-
def caseClass = unappSym.owner.linkedClass
531530

532531
// println("scrutineeTp = " + scrutineeTp.show)
533532

534-
lazy val caseAccessors = caseClass.caseAccessors.filter(_.is(Method))
535-
536-
def isSyntheticScala2Unapply(sym: Symbol) =
537-
sym.isAllOf(SyntheticCase) && sym.owner.is(Scala2x)
538-
539533
val mt: MethodType = unapp.widen match {
540534
case mt: MethodType => mt
541535
case pt: PolyType =>
@@ -564,9 +558,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
564558
val resTp = mt.finalResultType
565559

566560
val sig =
567-
if (isSyntheticScala2Unapply(unappSym) && caseAccessors.length == argLen)
568-
caseAccessors.map(_.info.asSeenFrom(mt.paramInfos.head, caseClass).widenExpr)
569-
else if (resTp.isRef(defn.BooleanClass))
561+
if (resTp.isRef(defn.BooleanClass))
570562
List()
571563
else {
572564
val isUnapplySeq = unappSym.name == nme.unapplySeq
@@ -584,7 +576,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
584576
if (arity > 0)
585577
productSelectorTypes(resTp, unappSym.srcPos)
586578
else {
587-
val getTp = resTp.select(nme.get).finalResultType.widen
579+
val getTp = resTp.select(nme.get).finalResultType.widenTermRefExpr
588580
if (argLen == 1) getTp :: Nil
589581
else productSelectorTypes(getTp, unappSym.srcPos)
590582
}

tests/patmat/i10085.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
enum Bool:
2+
case True
3+
case False
4+
5+
import Bool._
6+
7+
enum SBool[B <: Bool]:
8+
case STrue extends SBool[True.type]
9+
case SFalse extends SBool[False.type]
10+
11+
import SBool._
12+
13+
def f(b: SBool[True.type]): Unit = b match
14+
case STrue => ()

tests/patmat/i9190.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Test {
2+
case object X; type X = X.type
3+
case object Y; type Y = Y.type
4+
5+
type XorY = X | Y
6+
7+
val testee1: XorY = X
8+
testee1 match {
9+
case value: XorY => println(value)
10+
}
11+
12+
val testee2: Tuple1[XorY] = Tuple1(X)
13+
testee2 match {
14+
case Tuple1(value: XorY) => println(value)
15+
}
16+
17+
type IntOrString = Int | String
18+
19+
val testee3: Tuple1[IntOrString] = Tuple1(42)
20+
testee3 match {
21+
case Tuple1(value: IntOrString) => println(value)
22+
}
23+
}

0 commit comments

Comments
 (0)