Skip to content

Commit 8f2b6cf

Browse files
committed
Approximate MatchTypes with lub of case bodies, if non-recursive
1 parent 898ce33 commit 8f2b6cf

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,17 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
10301030
if tp1 ne tp1norm then recur(tp1norm, tp2)
10311031
else either(recur(tp11, tp2), recur(tp12, tp2))
10321032
case tp1: MatchType =>
1033+
def compareUpper =
1034+
val lub1 = tp1.cases.foldLeft(defn.NothingType: Type): (acc, case1) =>
1035+
if acc.exists then
1036+
val rhs = case1.resultType match { case defn.MatchCase(_, body) => body }
1037+
val isRecursive = rhs.existsPart(_.isInstanceOf[LazyRef])
1038+
if isRecursive then NoType else lub(acc, rhs)
1039+
else acc
1040+
if lub1.exists then
1041+
recur(lub1, tp2)
1042+
else
1043+
recur(tp1.underlying, tp2)
10331044
def compareMatch = tp2 match {
10341045
case tp2: MatchType =>
10351046
// we allow a small number of scrutinee types to be widened:
@@ -1047,7 +1058,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
10471058
tp1.cases.corresponds(tp2.cases)(isSubType)
10481059
case _ => false
10491060
}
1050-
(!caseLambda.exists || canWidenAbstract) && recur(tp1.underlying, tp2) || compareMatch
1061+
(!caseLambda.exists || canWidenAbstract) && compareUpper || compareMatch
10511062
case tp1: AnnotatedType if tp1.isRefining =>
10521063
isNewSubType(tp1.parent)
10531064
case JavaArrayType(elem1) =>

tests/pos/i19710.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.util.NotGiven
2+
3+
type HasName1 = [n] =>> [x] =>> x match {
4+
case n => true
5+
case _ => false
6+
}
7+
@main def Test = {
8+
summon[HasName1["foo"]["foo"] =:= true]
9+
summon[NotGiven[HasName1["foo"]["bar"] =:= true]]
10+
summon[Tuple.Filter[(1, "foo", 2, "bar"), HasName1["foo"]] =:= Tuple1["foo"]] // error
11+
}

0 commit comments

Comments
 (0)