Skip to content

Commit

Permalink
SI-6956 determine switchability by type, not tree
Browse files Browse the repository at this point in the history
Constant folding will set the type of a constant tree
to `ConstantType(Constant(folded))`, while the tree
itself can be many different things (in casu, an Ident).

We used to look at the tree directly when deciding whether
to emit a switch. Now we look at the tree's type. Voilà.
  • Loading branch information
adriaanm committed Jan 15, 2013
1 parent 621f7a5 commit a6b34b6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3494,8 +3494,10 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
val alternativesSupported = true
val canJump = true

object SwitchablePattern { def unapply(pat: Tree): Option[Tree] = pat match {
case Literal(const@Constant((_: Byte ) | (_: Short) | (_: Int ) | (_: Char ))) =>
// Constant folding sets the type of a constant tree to `ConstantType(Constant(folded))`
// The tree itself can be a literal, an ident, a selection, ...
object SwitchablePattern { def unapply(pat: Tree): Option[Tree] = pat.tpe match {
case ConstantType(const@Constant((_: Byte ) | (_: Short) | (_: Int ) | (_: Char ))) =>
Some(Literal(Constant(const.intValue))) // TODO: Java 7 allows strings in switches
case _ => None
}}
Expand Down
1 change: 1 addition & 0 deletions test/files/run/t6956.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2
26 changes: 26 additions & 0 deletions test/files/run/t6956.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import scala.tools.partest.IcodeTest

class Switches {
private[this] final val ONE = 1

def switchBad(i: Byte): Int = i match {
case ONE => 1
case 2 => 2
case 3 => 3
case _ => 0
}

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)
}

0 comments on commit a6b34b6

Please sign in to comment.