Skip to content

Commit fad8d45

Browse files
Handle sub cases in PatternMatcher
1 parent c4172e7 commit fad8d45

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class PatternMatcher extends MiniPhase {
3737

3838
override def transformMatch(tree: Match)(using Context): Tree =
3939
if (tree.isInstanceOf[InlineMatch]) tree
40+
else if tree.isSubMatch then
41+
// A sub match in a case def body will be transformed when the outer match is processed.
42+
// This assummes that no earlier miniphase needs sub matches to have been transformed before the outer match.
43+
tree
4044
else {
4145
// Widen termrefs with underlying `=> T` types. Otherwise ElimByName will produce
4246
// inconsistent types. See i7743.scala.
@@ -476,12 +480,23 @@ object PatternMatcher {
476480
}
477481
}
478482

479-
private def caseDefPlan(scrutinee: Symbol, cdef: CaseDef): Plan = {
480-
var onSuccess: Plan = ResultPlan(cdef.body)
481-
if (!cdef.guard.isEmpty)
482-
onSuccess = TestPlan(GuardTest, cdef.guard, cdef.guard.span, onSuccess)
483-
patternPlan(scrutinee, cdef.pat, onSuccess)
484-
}
483+
private def caseDefPlan(scrutinee: Symbol, cdef: CaseDef): Plan =
484+
val CaseDef(pat, guard, body) = cdef
485+
val caseDefBodyPlan: Plan = body match
486+
case t: SubMatch => subMatchPlan(t)
487+
case _ => ResultPlan(body)
488+
val onSuccess: Plan =
489+
if guard.isEmpty then caseDefBodyPlan
490+
else TestPlan(GuardTest, guard, guard.span, caseDefBodyPlan)
491+
patternPlan(scrutinee, pat, onSuccess)
492+
end caseDefPlan
493+
494+
// like matchPlan but without a final matchError ResultPlan at the end of SeqPlans
495+
// s.t. we fall back to the outer SeqPlan
496+
private def subMatchPlan(tree: SubMatch): Plan =
497+
letAbstract(tree.selector) { scrutinee =>
498+
tree.cases.map(caseDefPlan(scrutinee, _)).reduceRight(SeqPlan(_, _))
499+
}
485500

486501
private def matchPlan(tree: Match): Plan =
487502
letAbstract(tree.selector) { scrutinee =>

0 commit comments

Comments
 (0)