Skip to content

Commit 5e46b01

Browse files
Handle sub cases in PatternMatcher
1 parent 4c28954 commit 5e46b01

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.
@@ -482,12 +486,23 @@ object PatternMatcher {
482486
}
483487
}
484488

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

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

0 commit comments

Comments
 (0)