Skip to content

Commit 4b637df

Browse files
committed
merge even in the presence of bound captures
1 parent 0bc8f29 commit 4b637df

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

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

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -518,15 +518,36 @@ object PatternMatcher {
518518
class MergeTests extends PlanTransform {
519519
override def apply(plan: SeqPlan): Plan = {
520520
def tryMerge(plan1: Plan, plan2: Plan): Option[Plan] = {
521-
(plan1, plan2) match {
522-
case (plan1: TestPlan, plan2: TestPlan) if plan1 == plan2 =>
523-
plan1.onSuccess = SeqPlan(plan1.onSuccess, plan2.onSuccess)
524-
Some(plan1)
525-
526-
case (plan1: LetPlan, plan2: LetPlan) if isPatmatGenerated(plan2.sym) && initializer(plan1.sym) === initializer(plan2.sym) =>
527-
val newPlan2Body = new SubstituteIdent(plan2.sym, plan1.sym)(plan2.body)
528-
plan1.body = SeqPlan(plan1.body, newPlan2Body)
529-
Some(plan1)
521+
def skipNonPatmatGenedLets(plan: Plan): Plan = plan match {
522+
case LetPlan(sym, body) if !isPatmatGenerated(sym) =>
523+
skipNonPatmatGenedLets(body)
524+
case _ =>
525+
plan
526+
}
527+
528+
def transferNonPatmatGenedLets(originalPlan: Plan, newPlan: Plan): Plan = originalPlan match {
529+
case originalPlan: LetPlan if !isPatmatGenerated(originalPlan.sym) =>
530+
originalPlan.body = transferNonPatmatGenedLets(originalPlan.body, newPlan)
531+
originalPlan
532+
case _ =>
533+
newPlan
534+
}
535+
536+
(skipNonPatmatGenedLets(plan1), skipNonPatmatGenedLets(plan2)) match {
537+
case (testPlan1: TestPlan, testPlan2: TestPlan) if testPlan1 == testPlan2 =>
538+
/* Because testPlan2 is the same as testPlan1, it cannot possibly refer to
539+
* the symbols defined by any of the skipped lets.
540+
*/
541+
testPlan1.onSuccess = SeqPlan(testPlan1.onSuccess,
542+
transferNonPatmatGenedLets(plan2, testPlan2.onSuccess))
543+
Some(plan1) // that's the original plan1, on purpose
544+
545+
case (letPlan1: LetPlan, letPlan2: LetPlan) if initializer(letPlan1.sym) === initializer(letPlan2.sym) =>
546+
// By construction, letPlan1.sym and letPlan2.sym are patmat-generated
547+
val newPlan2Body = new SubstituteIdent(letPlan2.sym, letPlan1.sym)(letPlan2.body)
548+
letPlan1.body = SeqPlan(letPlan1.body,
549+
transferNonPatmatGenedLets(plan2, newPlan2Body))
550+
Some(plan1) // that's the original plan1, on purpose
530551

531552
case _ =>
532553
None

0 commit comments

Comments
 (0)