@@ -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