summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2007-07-11 21:28:24 +0000
committerBurak Emir <emir@epfl.ch>2007-07-11 21:28:24 +0000
commitc5bacffe8dcdeda88ce1e93282ff3eeba21c656a (patch)
tree0b908be8425075c97bc0fb27f22fa32db7a1d487 /src
parent4358c5019d4e7d6f3fc7767105ef9b2ca6ee6f20 (diff)
downloadscala-c5bacffe8dcdeda88ce1e93282ff3eeba21c656a.tar.gz
scala-c5bacffe8dcdeda88ce1e93282ff3eeba21c656a.tar.bz2
scala-c5bacffe8dcdeda88ce1e93282ff3eeba21c656a.zip
fix + small optimization, duplicating small bodies
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala41
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala7
2 files changed, 33 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index ad1b82c2e4..3ce4acb0f3 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -586,11 +586,28 @@ trait ParallelMatching {
def genBody(subst: List[Pair[Symbol,Symbol]], b:Tree)(implicit theOwner: Symbol, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = {
- bodies.get(b) match {
+ if(b.isInstanceOf[Literal]) { // small trees
+ bodies(b) = null // placeholder, for unreachable-code-detection
+ return b.duplicate
+ } else if (b.isInstanceOf[Throw]) {
+ bodies(b) = null // placeholder, for unreachable-code-detection
+ val (from,to) = List.unzip(subst)
+ val b2 = b.duplicate
+ new TreeSymSubstituter(from,to).traverse(b2)
+ return b2
+ } else if (b.isInstanceOf[Ident]) {
+ bodies(b) = null // placeholder, for unreachable-code-detection
+ val bsym = b.symbol
+ var su = subst
+ while(su ne Nil) {
+ val sh = su.head
+ if(sh._1 eq bsym) return Ident(sh._2) setType sh._2.tpe
+ su = su.tail
+ }
+ return b.duplicate
+ } else bodies.get(b) match {
case Some(EmptyTree, nb, 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 = nb match { case Block(_, LabelDef(_, origs, _)) =>
origs.map { p => Ident(subst.find { q => q._1 == p.symbol }.get._2) } // wrong!
@@ -601,10 +618,6 @@ 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)
@@ -678,15 +691,15 @@ trait ParallelMatching {
}
case ml: MixLiterals =>
- val (branches, defaultV, default) = ml.getTransition // tag body pairs
+ val (branches, defaultV, defaultRepOpt) = ml.getTransition // tag body pairs
if(settings_debug) {
Console.println("[[mix literal transition: branches \n"+(branches.mkString("","\n","")))
Console.println("defaults:"+defaultV)
- Console.println(default)
+ Console.println(defaultRepOpt)
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(defaultRepOpt.isEmpty) failTree else repToTree(defaultRepOpt.get, typed, handleOuter)
renamingBind(defaultV, ml.scrutinee, ndefault) // each v in defaultV gets bound to scrutinee
@@ -695,7 +708,8 @@ trait ParallelMatching {
makeIf(Equals(Ident(ml.scrutinee),lit), body, ndefault)
} else {
val defCase = CaseDef(mk_(definitions.IntClass.tpe), EmptyTree, ndefault)
- Match(Ident(ml.scrutinee), cases ::: defCase :: Nil)
+ val selector = Ident(ml.scrutinee)
+ Match(selector, cases ::: defCase :: Nil)
}
case mm:MixTypes =>
@@ -901,13 +915,16 @@ object Rep {
def covers(pats: List[Tree], comb:List[(Int,Symbol)]) =
comb forall {
case (i,sym) =>
- val p = pats(i);
+ val p = strip2(pats(i));
+ val res =
isDefaultPattern(p) || {
val symtpe = if(sym.hasFlag(symtab.Flags.MODULE)) {
singleType(sym.tpe.prefix, sym.linkedModuleOfClass) // e.g. None, Nil
} else sym.tpe
p.tpe.symbol == sym || symtpe <:< p.tpe
}
+ //Console.println("covers: sym="+sym+" p="+p+", p.tpe="+p.tpe+" ?"+res)
+ res
}
val coversAll = allcomb forall { combination => row exists { r => covers(r.pat, combination)}}
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index caaebd4e6a..18f7f06524 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -134,11 +134,12 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
return
case _:OutOfMemoryError =>
- cunit.error(cases.head.pos, "internal error (out of memory in parallel match algorithm")
+ cunit.error(cases.head.pos, "internal error (out of memory in parallel match algorithm)")
throw FatalError("died in parallel match algorithm" )
- case _:MatchError =>
- cunit.error(cases.head.pos, "internal error (match error in parallel match algorithm")
+ case e:MatchError =>
+ cunit.error(cases.head.pos, "internal error (match error in parallel match algorithm)"+e.getMessage)
+ e.printStackTrace()
throw FatalError("died in parallel match algorithm" )
case e =>