summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2007-06-21 14:02:56 +0000
committerBurak Emir <emir@epfl.ch>2007-06-21 14:02:56 +0000
commit30f41d643a482d21f1518abe0af39a182d54cf20 (patch)
tree074e9c3de501f8c3b88871461993dfed716946ae
parentaba747cf8d0145d6c10726151bf55ff997e8b0e6 (diff)
downloadscala-30f41d643a482d21f1518abe0af39a182d54cf20.tar.gz
scala-30f41d643a482d21f1518abe0af39a182d54cf20.tar.bz2
scala-30f41d643a482d21f1518abe0af39a182d54cf20.zip
fixed bug in ParallelMatching:MixLiterals (symp...
fixed bug in ParallelMatching:MixLiterals (symptom: "unreachable code")
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala59
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala5
-rw-r--r--src/library/scala/collection/immutable/SortedMap.scala6
3 files changed, 48 insertions, 22 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 9cf0ff216c..3e42a896d2 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -83,15 +83,15 @@ trait ParallelMatching {
var defaults: List[Int] = Nil
var defaultV: List[Symbol] = Nil
- // sorted e.g. case _ => 1,5,7
+ // sorted e.g. case _ => 1,5,7
private def insertDefault(tag: Int,vs:List[Symbol]) {
def ins(xs:List[Int]):List[Int] = xs match {
case y::ys if y > tag => y::ins(ys)
- case _ => tag :: Nil
+ case ys => tag :: ys
}
defaultV = defaultV:::vs
- defaults = ins(defaults)
+ defaults = ins(defaults)
}
class TagIndexPair(val tag:Int, val index: Int, val next: TagIndexPair) {}
@@ -111,14 +111,19 @@ trait ParallelMatching {
var tagIndexPairs: TagIndexPair = null
+ private def sanity(pos:Position,pvars:List[Symbol]) {
+ if(!pvars.isEmpty) cunit.error(pos, "nonsensical variable binding")
+ }
+
{
var xs = column
var i = 0;
while(!xs.isEmpty) { // forall
- xs.head match {
- case Literal(Constant(c:Int)) => insertTagIndexPair(c,i)
- case Literal(Constant(c:Char)) => insertTagIndexPair(c.toInt,i)
- case p if isDefaultPattern(p) => insertDefault(i,strip(p)._1)
+ val (pvars,p) = strip(xs.head)
+ p match {
+ case Literal(Constant(c:Int)) => sanity(p.pos, pvars); insertTagIndexPair(c,i)
+ case Literal(Constant(c:Char)) => sanity(p.pos, pvars); insertTagIndexPair(c.toInt,i)
+ case p if isDefaultPattern(p) => insertDefault(i,pvars)
}
i = i + 1
xs = xs.tail
@@ -135,7 +140,12 @@ trait ParallelMatching {
tagRows = rest.row(tagIndexPairs.index)::tagRows
tagIndexPairs = tagIndexPairs.next
}
- trs = (tag, Rep(rest.temp, tagRows)) :: trs
+ var tagRowsD:List[(List[Tree], List[(Symbol,Symbol)], Tree, Tree)] = Nil
+ var ds = defaults; while(ds ne Nil) {
+ tagRowsD = rest.row(ds.head) :: tagRowsD
+ ds = ds.tail
+ }
+ trs = (tag, Rep(rest.temp, tagRows ::: tagRowsD)) :: trs
}
trs
}
@@ -442,7 +452,8 @@ trait ParallelMatching {
case VariableRule(subst, EmptyTree, b) => bodies.get(b) match {
case Some(EmptyTree, b, theLabel) => //Console.println("H E L L O"+subst+" "+b)
-
+ if(b.isInstanceOf[Literal])
+ return b
// recover the order of the idents that is expected for the labeldef
val args = b match { case Block(_, LabelDef(_, origs, _)) =>
origs.map { p => Ident(subst.find { q => q._1 == p.symbol }.get._2) } // wrong!
@@ -453,12 +464,16 @@ trait ParallelMatching {
return body
case None =>
+ if(b.isInstanceOf[Literal]) {
+ bodies(b) = (EmptyTree, b, null) // unreachable code is detected via missing hash entries
+ return b
+ }
+ // this seems weird, but is necessary for sharing bodies. unnecessary for bodies that are not shared
var argtpes = subst map { case (v,_) => v.tpe }
val theLabel = targetLabel(theOwner, b.pos, "body"+b.hashCode, argtpes, b.tpe)
// make new value parameter for each vsym in subst
val vdefs = targetParams(subst)
- // this seems weird, but is necessary for sharing bodies. unnecessary for bodies that are not shared
var nbody: Tree = b
val vrefs = vdefs.map { p:ValDef => Ident(p.symbol) }
nbody = Block(vdefs:::List(Apply(Ident(theLabel), vrefs)), LabelDef(theLabel, subst.map(_._1), nbody))
@@ -468,19 +483,29 @@ trait ParallelMatching {
case VariableRule(subst,g,b) =>
throw CantHandleGuard
- case ml:MixLiterals=>
+ case ml: MixLiterals =>
val (branches, defaultV, default) = ml.getTransition // tag body pairs
-
+ if(settings.debug.value) {
+ Console.println("[[mix literal transition: branches \n"+(branches.mkString("","\n","")))
+ Console.println("defaults:"+defaultV)
+ Console.println(default)
+ Console.println("]]")
+ }
val cases = branches map { case (tag, rep) => CaseDef(Literal(tag), EmptyTree, repToTree(rep,typed,handleOuter)) }
- var ndefault = if(default.isEmpty) failTree else repToTree(default.get,typed,handleOuter)
+ var ndefault = if(default.isEmpty) failTree else repToTree(default.get, typed, handleOuter)
if(!defaultV.isEmpty) {
var to:List[Symbol] = Nil
var i = 0; while(i < defaultV.length) { i = i + 1; to = ml.scrutinee::to }
val tss = new TreeSymSubstituter(defaultV, to)
tss.traverse( ndefault )
}
- val defCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, ndefault)
- Match(Ident(ml.scrutinee), cases:::defCase::Nil)
+ if(cases.length == 1) {
+ val CaseDef(lit,_,body) = cases.head
+ makeIf(Equals(Ident(ml.scrutinee),lit), body, ndefault)
+ } else {
+ val defCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, ndefault)
+ Match(Ident(ml.scrutinee), cases ::: defCase :: Nil)
+ }
case mm:MixTypes =>
val (casted,srep,frep) = mm.getTransition
@@ -510,7 +535,7 @@ trait ParallelMatching {
vdefs = typed { ValDef(casted, gen.mkAsInstanceOf(typed{Ident(mm.scrutinee)}, casted.tpe))} :: vdefs
typed { makeIf(cond, Block(vdefs,succ), fail) }
- case mu:MixUnapply =>
+ case mu: MixUnapply =>
val (uacall,vdefs,srep,frep) = mu.getTransition
//Console.println("getTransition"+(uacall,vdefs,srep,frep))
val succ = repToTree(srep, typed, handleOuter)
@@ -708,7 +733,7 @@ object Rep {
for (tmp <- temp) pad(tmp.name.toString)
sb.append('\n')
for ((r,i) <- row.zipWithIndex) {
- for (c <- r._1 ::: List(r._2, r._3)) {
+ for (c <- r._1 ::: List(r._2, r._3, r._4)) {
pad(c.toString)
}
sb.append('\n')
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index eadfdbee81..33b8385c26 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -175,8 +175,9 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
val CaseDef(_,_,b) = cases(i)
//DEBUG("*** damn, unreachable!")
//Console.println("damn, unreachable!")
- //for (b <- bodies)
- // Console.println(b)
+ if(settings.debug.value) {
+ Console.println("bodies:"+bodies.mkString("","\n",""))
+ }
cunit.error(b.pos, "unreachable code")
}
diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala
index a26f734755..a5c73764c8 100644
--- a/src/library/scala/collection/immutable/SortedMap.scala
+++ b/src/library/scala/collection/immutable/SortedMap.scala
@@ -25,14 +25,14 @@ trait SortedMap[A,+B] extends Map[A,B] with collection.SortedMap[A,B] {
override def transform[C](f: (A, B) => C): SortedMap[A, C] = {
var res = empty[C]
- foreach { case Pair(key, value) => res = res.update(key, f(key, value)) }
+ foreach { case (key, value) => res = res.update(key, f(key, value)) }
res
}
override def filter(p: Pair[A, B] => Boolean): SortedMap[A, B] = {
var res = this
foreach {
- case kv @ Pair(key, _) => if (!p(kv)) { res = res - key }
+ case kv @ (key, _) => if (!p(kv)) { res = res - key }
}
res
}
-} \ No newline at end of file
+}