summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-01-10 14:43:00 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-01-11 14:36:02 -0800
commit38958f458cec09dacece690b2376d96fc7758972 (patch)
treec4ae0e325edab7da39a157e9a0c05469f8d6a672
parent64ec51b31f9563580e250ac45714b9d3d86abde1 (diff)
downloadscala-38958f458cec09dacece690b2376d96fc7758972.tar.gz
scala-38958f458cec09dacece690b2376d96fc7758972.tar.bz2
scala-38958f458cec09dacece690b2376d96fc7758972.zip
SI-6955 switch emission no longer foiled by type alias
dealiasWiden the type of the scrutinee before checking it's switchable now with tests! (using IcodeTest since javap is not available everywhere) rebase of #1879
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala2
-rw-r--r--test/files/run/t6955.check1
-rw-r--r--test/files/run/t6955.scala28
3 files changed, 30 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 49eca828a9..5f70da6a63 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -3520,7 +3520,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
override def emitSwitch(scrut: Tree, scrutSym: Symbol, cases: List[List[TreeMaker]], pt: Type, matchFailGenOverride: Option[Tree => Tree], unchecked: Boolean): Option[Tree] = { import CODE._
val regularSwitchMaker = new RegularSwitchMaker(scrutSym, matchFailGenOverride, unchecked)
// TODO: if patterns allow switch but the type of the scrutinee doesn't, cast (type-test) the scrutinee to the corresponding switchable type and switch on the result
- if (regularSwitchMaker.switchableTpe(scrutSym.tpe)) {
+ if (regularSwitchMaker.switchableTpe(scrutSym.tpe.dealiasWiden)) {
val caseDefsWithDefault = regularSwitchMaker(cases map {c => (scrutSym, c)}, pt)
if (caseDefsWithDefault isEmpty) None // not worth emitting a switch.
else {
diff --git a/test/files/run/t6955.check b/test/files/run/t6955.check
new file mode 100644
index 0000000000..0cfbf08886
--- /dev/null
+++ b/test/files/run/t6955.check
@@ -0,0 +1 @@
+2
diff --git a/test/files/run/t6955.scala b/test/files/run/t6955.scala
new file mode 100644
index 0000000000..980aa420cc
--- /dev/null
+++ b/test/files/run/t6955.scala
@@ -0,0 +1,28 @@
+import scala.tools.partest.IcodeTest
+
+// this class should compile to code that uses switches (twice)
+class Switches {
+ type Tag = Byte
+
+ def switchBad(i: Tag): Int = i match { // notice type of i is Tag = Byte
+ case 1 => 1
+ case 2 => 2
+ case 3 => 3
+ case _ => 0
+ }
+
+ // this worked before, should keep working
+ def switchOkay(i: Byte): Int = i match {
+ case 1 => 1
+ case 2 => 2
+ case 3 => 3
+ case _ => 0
+ }
+}
+
+object Test extends IcodeTest {
+ // ensure we get two switches out of this -- ignore the rest of the output for robustness
+ // exclude the constant we emit for the "SWITCH ..." string below (we get the icode for all the code you see in this file)
+ override def show() = println(collectIcode("").filter(x => x.indexOf("SWITCH ...") >= 0 && x.indexOf("CONSTANT(") == -1).size)
+}
+