diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index 8bac04c0e509..e470af9c43cb 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -711,9 +711,14 @@ object PatternMatcher { (tpe isRef defn.ShortClass) || (tpe isRef defn.CharClass) - def isIntConst(tree: Tree) = tree match { - case Literal(const) => const.isIntRange - case _ => false + val seen = mutable.Set[Int]() + + def isNewIntConst(tree: Tree) = tree match { + case Literal(const) if const.isIntRange && !seen.contains(const.intValue) => + seen += const.intValue + true + case _ => + false } // An extractor to recover the shape of plans that can become alternatives @@ -725,7 +730,7 @@ object PatternMatcher { val alts = List.newBuilder[Tree] def rec(innerPlan: Plan): Boolean = innerPlan match { case SeqPlan(TestPlan(EqualTest(tree), scrut, _, ReturnPlan(`innerLabel`)), tail) - if scrut === scrutinee && isIntConst(tree) => + if scrut === scrutinee && isNewIntConst(tree) => alts += tree rec(tail) case ReturnPlan(`outerLabel`) => @@ -746,7 +751,7 @@ object PatternMatcher { def recur(plan: Plan): List[(List[Tree], Plan)] = plan match { case SeqPlan(testPlan @ TestPlan(EqualTest(tree), scrut, _, ons), tail) - if scrut === scrutinee && isIntConst(tree) && !canFallThrough(ons) => + if scrut === scrutinee && !canFallThrough(ons) && isNewIntConst(tree) => (tree :: Nil, ons) :: recur(tail) case SeqPlan(AlternativesPlan(alts, ons), tail) => (alts, ons) :: recur(tail) diff --git a/tests/pos/i5402.scala b/tests/pos/i5402.scala new file mode 100644 index 000000000000..fa4e23ed9ce6 --- /dev/null +++ b/tests/pos/i5402.scala @@ -0,0 +1,27 @@ +object Main { + val a: Int = 4 + a match { + case 1 => println("1") + case 1 | 2 => println("1 or 2") + } + + a match { + case 1 => 1 + case 0 | 0 => 0 + case 2 | 2 | 2 | 3 | 2 | 3 => 0 + case 4 | (_ @ 4) => 0 + case _ => -1 + } + + a match { + case 1 => 1 + case 0 | 0 => 0 + case 2 | 2 | 2 | 3 | 2 | 3 => 0 + case _ => -1 + } + + a match { + case 0 | 1 => 0 + case 1 => 1 + } +}