@@ -48,6 +48,9 @@ object PatternMatcher {
4848
4949 final val selfCheck = false // debug option, if on we check that no case gets generated twice
5050
51+ /** Minimal number of cases to emit a switch */
52+ final val MinSwitchCases = 4
53+
5154 /** Was symbol generated by pattern matcher? */
5255 def isPatmatGenerated (sym : Symbol )(implicit ctx : Context ): Boolean =
5356 sym.is(Synthetic ) &&
@@ -845,10 +848,10 @@ object PatternMatcher {
845848
846849 /** Emit cases of a switch */
847850 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)
850851 case (default : Plan ) :: Nil =>
851852 CaseDef (Underscore (defn.IntType ), EmptyTree , emit(default)) :: Nil
853+ case TestPlan (EqualTest (tree), _, _, ons, _) :: cases1 =>
854+ CaseDef (tree, EmptyTree , emit(ons)) :: emitSwitchCases(cases1)
852855 }
853856
854857 /** If selfCheck is `true`, used to check whether a tree gets generated twice */
@@ -863,7 +866,7 @@ object PatternMatcher {
863866 plan match {
864867 case plan : TestPlan =>
865868 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
867870 Match (plan.scrutinee, emitSwitchCases(switchCases))
868871 else {
869872 /** Merge nested `if`s that have the same `else` branch into a single `if`.
@@ -969,12 +972,21 @@ object PatternMatcher {
969972 case Block (_, Match (_, cases)) => cases
970973 case _ => Nil
971974 }
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)
975989 }
976- if (numConsts(resultCases) < numConsts(original.cases))
977- ctx.warning(UnableToEmitSwitch (), original.pos)
978990 case _ =>
979991 }
980992
0 commit comments