@@ -48,6 +48,9 @@ object PatternMatcher {
48
48
49
49
final val selfCheck = false // debug option, if on we check that no case gets generated twice
50
50
51
+ /** Minimal number of cases to emit a switch */
52
+ final val MinSwitchCases = 4
53
+
51
54
/** Was symbol generated by pattern matcher? */
52
55
def isPatmatGenerated (sym : Symbol )(implicit ctx : Context ): Boolean =
53
56
sym.is(Synthetic ) &&
@@ -845,10 +848,10 @@ object PatternMatcher {
845
848
846
849
/** Emit cases of a switch */
847
850
private def emitSwitchCases (cases : List [Plan ]): List [CaseDef ] = (cases : @ unchecked) match {
848
- case TestPlan (EqualTest (tree), _, _, ons, _) :: cases1 =>
849
- CaseDef (tree, EmptyTree , emit(ons)) :: emitSwitchCases(cases1)
850
851
case (default : Plan ) :: Nil =>
851
852
CaseDef (Underscore (defn.IntType ), EmptyTree , emit(default)) :: Nil
853
+ case TestPlan (EqualTest (tree), _, _, ons, _) :: cases1 =>
854
+ CaseDef (tree, EmptyTree , emit(ons)) :: emitSwitchCases(cases1)
852
855
}
853
856
854
857
/** If selfCheck is `true`, used to check whether a tree gets generated twice */
@@ -863,7 +866,7 @@ object PatternMatcher {
863
866
plan match {
864
867
case plan : TestPlan =>
865
868
val switchCases = collectSwitchCases(plan)
866
- if (switchCases.lengthCompare(4 ) >= 0 ) // at least 3 cases + default
869
+ if (switchCases.lengthCompare(MinSwitchCases ) >= 0 ) // at least 3 cases + default
867
870
Match (plan.scrutinee, emitSwitchCases(switchCases))
868
871
else {
869
872
/** Merge nested `if`s that have the same `else` branch into a single `if`.
@@ -969,12 +972,21 @@ object PatternMatcher {
969
972
case Block (_, Match (_, cases)) => cases
970
973
case _ => Nil
971
974
}
972
- def numConsts (cdefs : List [CaseDef ]): Int = {
973
- val tpes = cdefs.map(_.pat.tpe)
974
- tpes.toSet.size
975
+ def typesInPattern (pat : Tree ): List [Type ] = pat match {
976
+ case Alternative (pats) => pats.flatMap(typesInPattern)
977
+ case _ => pat.tpe :: Nil
978
+ }
979
+ def typesInCases (cdefs : List [CaseDef ]): List [Type ] =
980
+ cdefs.flatMap(cdef => typesInPattern(cdef.pat))
981
+ def numTypes (cdefs : List [CaseDef ]): Int =
982
+ typesInCases(cdefs).toSet.size: Int // without the type ascription, testPickling fails because of #2840.
983
+ if (numTypes(resultCases) < numTypes(original.cases)) {
984
+ patmatch.println(i " switch warning for ${ctx.compilationUnit}" )
985
+ patmatch.println(i " original types: ${typesInCases(original.cases)}%, % " )
986
+ patmatch.println(i " switch types : ${typesInCases(resultCases)}%, % " )
987
+ patmatch.println(i " tree = $result" )
988
+ ctx.warning(UnableToEmitSwitch (numTypes(original.cases) < MinSwitchCases ), original.pos)
975
989
}
976
- if (numConsts(resultCases) < numConsts(original.cases))
977
- ctx.warning(UnableToEmitSwitch (), original.pos)
978
990
case _ =>
979
991
}
980
992
0 commit comments