summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2007-08-06 09:58:54 +0000
committerBurak Emir <emir@epfl.ch>2007-08-06 09:58:54 +0000
commit4574bcbd6783fa0f7fe1de2bbb445c8a4eb54a5b (patch)
tree1381cea2ef2f21699e23ae94026398075ff901e8
parenteb21be47d8e2fe834fce71aaed59cac129410699 (diff)
downloadscala-4574bcbd6783fa0f7fe1de2bbb445c8a4eb54a5b.tar.gz
scala-4574bcbd6783fa0f7fe1de2bbb445c8a4eb54a5b.tar.bz2
scala-4574bcbd6783fa0f7fe1de2bbb445c8a4eb54a5b.zip
-Ycasetags optimization
fixed 1253
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala3
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala44
-rw-r--r--src/compiler/scala/tools/nsc/matching/TransMatcher.scala1
-rw-r--r--test/files/run/patmatnew.scala7
4 files changed, 37 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index fd71f7f666..2ce8543bb0 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -141,6 +141,9 @@ class Settings(error: String => Unit) {
val stop = PhasesSetting ("-Ystop", "Stop after phase")
val Xwarndeadcode = BooleanSetting ("-Ywarn-dead-code", "Emit warnings for dead code")
+ val Xcasetags = ChoiceSetting("-Ycasetags", "test integer tags for case classes", List("on","off"),
+ /*default*/"off")
+
/** scaladoc specific options */
val pagebottom = StringSetting ("-bottom", "pagebottom", "Include bottom text for each page", "").dependsOn(doc)
val doccharset = StringSetting ("-charset", "doccharset", "Charset for cross-platform viewing of generated documentation.", "").dependsOn(doc)
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 4368ec7074..d4a8b4b0da 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -29,10 +29,15 @@ trait ParallelMatching {
// ---------------------------------- data
- sealed trait RuleApplication
- case class ErrorRule extends RuleApplication
- case class VariableRule(subst:List[Pair[Symbol,Symbol]], guard: Tree, body: Tree, guardedRest:Rep) extends RuleApplication
-
+ sealed trait RuleApplication {
+ def scrutinee:Symbol
+ }
+ case class ErrorRule extends RuleApplication {
+ def scrutinee:Symbol = throw new RuntimeException("this never happens")
+ }
+ case class VariableRule(subst:List[Pair[Symbol,Symbol]], guard: Tree, body: Tree, guardedRest:Rep) extends RuleApplication {
+ def scrutinee:Symbol = throw new RuntimeException("this never happens")
+ }
def MixtureRule(scrutinee:Symbol, column:List[Tree], rest:Rep): RuleApplication = {
def isSimpleIntSwitch: Boolean = {
(isSameType(scrutinee.tpe.widen, definitions.IntClass.tpe)/*||
@@ -97,22 +102,20 @@ trait ParallelMatching {
}
*/
if(isSimpleIntSwitch) {
- //if(settings_debug) { Console.println("MixLiteral") }
+ if(settings_debug) { Console.println("MixLiteral") }
return new MixLiterals(scrutinee, column, rest)
}
- /*
- if((column.length > 1) && isFlatCases(column)) {
+ if(settings_casetags && (column.length > 1) && isFlatCases(column)) {
if(settings_debug) {
Console.println("flat cases!"+column)
- Console.println(scrutinee.tpe./*?type?*/symbol.children)
+ Console.println(scrutinee.tpe.typeSymbol.children)
Console.println(scrutinee.tpe.member(nme.tag))
- Console.println(column.map { x => x.tpe./*?type?*/symbol.tag })
+ //Console.println(column.map { x => x.tpe./*?type?*/symbol.tag })
}
return new MixCases(scrutinee, column, rest)
// if(scrutinee.tpe./*?type?*/symbol.hasFlag(symtab.Flags.SEALED)) new MixCasesSealed(scrutinee, column, rest)
// else new MixCases(scrutinee, column, rest)
}
- */
//Console.println("isUnapplyHead")
if(isUnapplyHead) {
if(settings_debug) { Console.println("MixUnapply") }
@@ -160,7 +163,12 @@ trait ParallelMatching {
var tagIndexPairs: TagIndexPair = null
protected def grabTemps: List[Symbol] = rest.temp
- protected def grabRow(index:Int): Row = rest.row(index)
+ protected def grabRow(index:Int): Row = rest.row(index) match {
+ case r @ Row(pats,s,g,b) => if(defaultV.isEmpty) r else {
+ val nbindings = s:::defaultV.toList.map { v => (v,scrutinee) }
+ Row(pats, nbindings, g, b)
+ }
+ }
/** inserts row indices using in to list of tagindexpairs*/
protected def tagIndicesToReps = {
@@ -222,7 +230,9 @@ trait ParallelMatching {
override def grabTemps = scrutinee::rest.temp
override def grabRow(index:Int) = rest.row(tagIndexPairs.index) match {
- case Row(pats,s,g,b) => Row(column(tagIndexPairs.index)::pats,s,g,b)
+ case Row(pats,s,g,b) =>
+ val nbindings = s ::: defaultV.toList.map { v => (v,scrutinee) }
+ Row(column(tagIndexPairs.index)::pats, nbindings, g, b)
}
/*{
@@ -495,7 +505,7 @@ trait ParallelMatching {
case _ if (patternType <:< pat.tpe) || isDefaultPattern(pat) =>
//Console.println("current pattern is *more general*")
- (EmptyTree::ms, (j,dummies)::ss, (j,pat)::rs); // subsuming (matched *and* remaining pattern)
+ (EmptyTree::ms, (j, dummies)::ss, (j,pat)::rs); // subsuming (matched *and* remaining pattern)
case _ =>
//Console.println("current pattern tests something else")
@@ -516,7 +526,7 @@ trait ParallelMatching {
/** returns casted symbol, success matrix and optionally fail matrix for type test on the top of this column */
final def getTransition(implicit theOwner: Symbol): (Symbol, Rep, Option[Rep]) = {
- //DEBUG("*** getTransition! of "+this.toString)
+ //Console.println("*** getTransition! of "+this.toString)
// the following works for type tests... what fudge is necessary for value comparisons?
// type test
casted = if(scrutinee.tpe =:= patternType) scrutinee else newVar(scrutinee.pos, patternType)
@@ -559,7 +569,6 @@ trait ParallelMatching {
//Console.println("pats:"+pats)
//Console.println("opats:"+pats)
//debug
-
// don't substitute eagerly here, problems with bodies that can
// be reached with several routes... impossible to find one-fits-all ordering.
@@ -621,7 +630,7 @@ trait ParallelMatching {
val (from,to) = List.unzip(subst)
val b2 = origbody.duplicate
new TreeSymSubstituter(from,to).traverse(b2)
- val res = typed{ b2 }
+ val res = typed{ b2 }
return res
case _:Ident =>
bodies(origbody) = null // placeholder, for unreachable-code-detection
@@ -741,7 +750,6 @@ trait ParallelMatching {
var ndefault = if(defaultRepOpt.isEmpty) failTree else repToTree(defaultRepOpt.get, handleOuter)
renamingBind(defaultV, ml.scrutinee, ndefault) // each v in defaultV gets bound to scrutinee
-
if(cases.length == 1) {
val CaseDef(lit,_,body) = cases.head
makeIf(Equals(Ident(ml.scrutinee),lit), body, ndefault)
@@ -755,7 +763,7 @@ trait ParallelMatching {
case mm:MixTypes =>
val (casted,srep,frep) = mm.getTransition
- //DEBUG("--- mixture \n succ \n"+srep.toString+"\n fail\n"+frep.toString)
+ //Console.println("--- mixture \n succ \n"+srep.toString+"\n fail\n"+frep.toString)
//val cond = typed{gen.mkIsInstanceOf(Ident(mm.scrutinee), casted.tpe)}
//Console.println("casted.tpe="+casted.tpe)
val condUntyped = condition(casted.tpe, mm.scrutinee)
diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
index b16d30b7ff..b875def20d 100644
--- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
+++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
@@ -28,6 +28,7 @@ trait TransMatcher { self: transform.ExplicitOuter =>
final val settings_squeeze = settings.Xmatchalgo.value != "incr"
final val settings_useParallel = settings.Xmatchalgo.value != "incr"
final val settings_useIncr = settings.Xmatchalgo.value != "par"
+ final val settings_casetags = settings.Xcasetags.value == "on"
def containsBinding(pat: Tree): Boolean = {
var generatedVars = false
diff --git a/test/files/run/patmatnew.scala b/test/files/run/patmatnew.scala
index 63b40769ff..cce5bacc46 100644
--- a/test/files/run/patmatnew.scala
+++ b/test/files/run/patmatnew.scala
@@ -192,6 +192,13 @@ object Test extends TestConsoleMain {
}
+ object Test1253 { // compile-only
+ def foo(t : (Int, String)) = t match {
+ case (1, "") => throw new Exception
+ case (r, _) => throw new Exception(r.toString)
+ }
+ }
+
object Foo1 {
class Bar1(val x : String)
def p(b : Bar1) = Console.println(b.x)