Skip to content

Commit c25edde

Browse files
committed
Lub MatchTypeTree case body types and store as the inferred bound
1 parent 8f2b6cf commit c25edde

File tree

2 files changed

+10
-13
lines changed

2 files changed

+10
-13
lines changed

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

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,17 +1030,6 @@ 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)
10441033
def compareMatch = tp2 match {
10451034
case tp2: MatchType =>
10461035
// we allow a small number of scrutinee types to be widened:
@@ -1058,7 +1047,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
10581047
tp1.cases.corresponds(tp2.cases)(isSubType)
10591048
case _ => false
10601049
}
1061-
(!caseLambda.exists || canWidenAbstract) && compareUpper || compareMatch
1050+
(!caseLambda.exists || canWidenAbstract) && recur(tp1.underlying, tp2) || compareMatch
10621051
case tp1: AnnotatedType if tp1.isRefining =>
10631052
isNewSubType(tp1.parent)
10641053
case JavaArrayType(elem1) =>

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2373,7 +2373,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
23732373
report.error(MatchTypeScrutineeCannotBeHigherKinded(sel1Tpe), sel1.srcPos)
23742374
val pt1 = if (bound1.isEmpty) pt else bound1.tpe
23752375
val cases1 = tree.cases.mapconserve(typedTypeCase(_, sel1Tpe, pt1))
2376-
assignType(cpy.MatchTypeTree(tree)(bound1, sel1, cases1), bound1, sel1, cases1)
2376+
val bound2 = if tree.bound.isEmpty then
2377+
val lub = cases1.foldLeft(defn.NothingType: Type): (acc, case1) =>
2378+
if !acc.exists then NoType
2379+
else if case1.body.tpe.existsPart(_.isInstanceOf[LazyRef]) then NoType
2380+
else acc | TypeOps.avoid(case1.body.tpe, patVars(case1))
2381+
if lub.exists then TypeTree(lub, inferred = true)
2382+
else bound1
2383+
else bound1
2384+
assignType(cpy.MatchTypeTree(tree)(bound2, sel1, cases1), bound2, sel1, cases1)
23772385
}
23782386

23792387
def typedByNameTypeTree(tree: untpd.ByNameTypeTree)(using Context): ByNameTypeTree = tree.result match

0 commit comments

Comments
 (0)