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