summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2007-07-25 02:01:33 +0000
committerBurak Emir <emir@epfl.ch>2007-07-25 02:01:33 +0000
commita64786e441954e1b4fd9bf8731949117763c24d6 (patch)
tree6b80b382e439012ddfc13df914bba0c63a2464a5 /src
parentd6f27a8d9ca9b0207e85a594cc6c36588c346240 (diff)
downloadscala-a64786e441954e1b4fd9bf8731949117763c24d6.tar.gz
scala-a64786e441954e1b4fd9bf8731949117763c24d6.tar.bz2
scala-a64786e441954e1b4fd9bf8731949117763c24d6.zip
Par..
changed some .symbol calls to typeSymbol/termSymbol fixed a bug that would expand case class if column-head is not caseclass (*) removed generation of useless jmp in genbody moved helper functions to PatternNodes Erasure moved up unreachable code that was detected after fix (*)
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala217
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala39
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternNodes.scala20
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
4 files changed, 138 insertions, 142 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 8d6cedf1ce..b41a188585 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -13,15 +13,19 @@ import scala.tools.nsc.util.Position
* @author Burak Emir
*/
trait ParallelMatching {
- self: transform.ExplicitOuter with PatternMatchers with CodeFactory =>
+ self: transform.ExplicitOuter with PatternMatchers with PatternNodes with CodeFactory =>
import global._
import typer.typed
-
- def isCaseClass(tpe: Type) = tpe match {
- case TypeRef(_, sym, _) => sym.hasFlag(symtab.Flags.CASE)
- case _ => false
- }
+ import symtab.Flags
+
+ // problem: this works for types, but sometimes term symbol have case flag, see isFlatCases
+ def isCaseClass(tpe: Type) = //before: tpe.symbol.hasFlag(Flags.CASE)
+ tpe match {
+ case TypeRef(_, sym, _) =>
+ sym.hasFlag(symtab.Flags.CASE)
+ case _ => false
+ }
// ---------------------------------- data
@@ -64,21 +68,21 @@ trait ParallelMatching {
// true if pattern type is direct subtype of scrutinee (can't use just <:< cause have to take variance into account)
def directSubtype(ptpe:Type) =
- (ptpe.parents.exists { x => ((x./*?type?*/symbol eq scrutinee.tpe./*?type?*/symbol) && (x <:< scrutinee.tpe))});
+ (ptpe.parents.exists { x => ((x.typeSymbol eq scrutinee.tpe.typeSymbol) && (x <:< scrutinee.tpe))});
// true if each pattern type is case and direct subtype of scrutinee
def isFlatCases(col:List[Tree]): Boolean = (col eq Nil) || {
strip2(col.head) match {
case a @ Apply(fn,_) =>
- ((a.tpe./*?type?*/symbol.flags & symtab.Flags.CASE) != 0) && directSubtype( a.tpe ) && isFlatCases(col.tail)
+ isCaseClass(a.tpe) && directSubtype( a.tpe ) && isFlatCases(col.tail)
case t @ Typed(_,tpt) =>
- ( (tpt.tpe./*?type?*/symbol.flags & symtab.Flags.CASE) != 0) && directSubtype( t.tpe ) && isFlatCases(col.tail)
+ isCaseClass(tpt.tpe) && directSubtype( t.tpe ) && isFlatCases(col.tail)
case Ident(nme.WILDCARD) =>
isFlatCases(col.tail) // treat col.tail specially?
case i @ Ident(n) => // n ne nme.WILDCARD
- ( (i.symbol.flags & symtab.Flags.CASE) != 0) && directSubtype( i.tpe ) && isFlatCases(col.tail)
+ ( (i.symbol.flags & Flags.CASE) != 0) && directSubtype( i.tpe ) && isFlatCases(col.tail)
case s @ Select(_,_) => // i.e. scala.Nil
- ( (s.symbol.flags & symtab.Flags.CASE) != 0) && directSubtype( s.tpe ) && isFlatCases(col.tail)
+ ( (s.symbol.flags & Flags.CASE) != 0) && directSubtype( s.tpe ) && isFlatCases(col.tail)
case p =>
//Console.println(p.getClass)
false
@@ -211,7 +215,7 @@ trait ParallelMatching {
insertDefault(i,strip1(xs.head))
else
insertTagIndexPair(p.tpe./*?type?*/symbol.tag, i)
- i = i + 1
+ i += 1
xs = xs.tail
}
}
@@ -261,7 +265,7 @@ trait ParallelMatching {
}
protected override def haveDefault: Boolean =
- ((defaultIndexSet eq null) && super.haveDefault) | (defaultIndexSet.underlying != 0)
+ if(defaultIndexSet eq null) super.haveDefault else (defaultIndexSet.underlying != 0)
override def getDefaultRows: List[Row] = {
if(theDefaultRows ne null)
@@ -291,13 +295,12 @@ trait ParallelMatching {
var xs = column
var i = 0;
while(xs ne Nil) { // forall
- 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)
+ strip(xs.head) match {
+ case (pvars, p @ Literal(Constant(c:Int))) => sanity(p.pos, pvars); insertTagIndexPair(c,i)
+ case (pvars, p @ Literal(Constant(c:Char))) => sanity(p.pos, pvars); insertTagIndexPair(c.toInt,i)
+ case (pvars, p ) if isDefaultPattern(p) => insertDefault(i,pvars)
}
- i = i + 1
+ i += 1
xs = xs.tail
}
}
@@ -378,7 +381,7 @@ trait ParallelMatching {
vsyms = vchild :: vsyms
dummies = EmptyTree::dummies
ts = ts.tail
- i = i + 1
+ i += 1
}
val ntemps = vsyms.reverse ::: scrutinee :: rest.temp
dummies = dummies.reverse
@@ -404,7 +407,7 @@ trait ParallelMatching {
var subsumed: List[(Int,List[Tree])] = Nil // row index and subpatterns
var remaining: List[(Int,Tree)] = Nil // row index and pattern
- val isExhaustive = !scrutinee.tpe./*?type?*/symbol.hasFlag(symtab.Flags.SEALED) || {
+ val isExhaustive = !scrutinee.tpe.typeSymbol.hasFlag(symtab.Flags.SEALED) || {
//DEBUG("check exha for column "+column)
val tpes = column.map {x => /*Console.println("--x:"+x+":"+x.tpe); */ x.tpe./*?type?*/symbol}
scrutinee.tpe./*?type?*/symbol.children.forall { sym => tpes.contains(sym) }
@@ -416,7 +419,7 @@ trait ParallelMatching {
//case p@Apply(_,_) if !p.tpe./*?type?*/symbol.hasFlag(symtab.Flags.CASE) => ConstantType(new NamedConstant(p))
case _ => column.head.tpe
}
- private val isCaseHead = patternType./*?type?*/symbol.hasFlag(symtab.Flags.CASE)
+ private val isCaseHead = isCaseClass(patternType)
private val dummies = if(!isCaseHead) Nil else patternType./*?type?*/symbol.caseFieldAccessors.map { x => EmptyTree }
//Console.println("isCaseHead = "+isCaseHead)
@@ -428,8 +431,8 @@ trait ParallelMatching {
pat match {
case Bind(_,p) =>
subpatterns(p)
- case app @ Apply(fn, pats) if app.tpe./*?type?*/symbol.hasFlag(symtab.Flags.CASE) && (fn.symbol eq null)=>
- pats
+ case app @ Apply(fn, pats) if isCaseClass(app.tpe) && (fn.symbol eq null)=>
+ if(isCaseHead) pats else dummies
case Apply(fn,xs) => assert((xs.isEmpty) && (fn.symbol ne null)); dummies // named constant
case _: UnApply =>
dummies
@@ -498,7 +501,7 @@ trait ParallelMatching {
//Console.println("current pattern tests something else")
(ms,ss,(j,pat)::rs)
}
- j = j + 1
+ j += 1
pats = pats.tail
}
this.moreSpecific = sr._1.reverse
@@ -523,7 +526,7 @@ trait ParallelMatching {
val nmatrix = {
//Console.println("casted:"+casted)
//Console.println("casted.case:"+casted.tpe./*?type?*/symbol.hasFlag(symtab.Flags.CASE))
- var ntemps = if(casted.tpe./*?type?*/symbol.hasFlag(symtab.Flags.CASE)) casted.caseFieldAccessors map {
+ var ntemps = if(isCaseClass(casted.tpe)) casted.caseFieldAccessors map {
meth =>
val ctemp = newVar(scrutinee.pos, casted.tpe.memberType(meth).resultType)
if(scrutinee.hasFlag(symtab.Flags.CAPTURED))
@@ -543,7 +546,7 @@ trait ParallelMatching {
//moreSpecificIndices = Some(j::moreSpecificIndices)
(j,mspat::pats)
}
- //Console.println("MOS "+subtests)
+ //Console.println("more specific, subtests "+subtests)
}
ntemps = ntemps ::: rest.temp
val ntriples = subtests map {
@@ -566,7 +569,7 @@ trait ParallelMatching {
}
if(settings_debug) {
Console.println("ntemps = "+ntemps.mkString("[["," , ","]]"))
- Console.println("ntriples = "+ntriples.mkString("[["," , ","]]"))
+ Console.println("ntriples = "+ntriples.mkString("[[\n","\n, ","\n]]"))
}
Rep(ntemps, ntriples) /*setParent this*/
}
@@ -592,52 +595,67 @@ trait ParallelMatching {
}
- final def genBody(subst: List[Pair[Symbol,Symbol]], b:Tree)(implicit theOwner: Symbol, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = {
- if(b.isInstanceOf[Literal]) { // small trees
- bodies(b) = null // placeholder, for unreachable-code-detection
- return typed{ 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 typed{ 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 typed{ Ident(sh._2) }
- su = su.tail
- }
- return typed{ b.duplicate }
- } else bodies.get(b) match {
-
- case Some(EmptyTree, nb, theLabel) => //Console.println("H E L L O"+subst+" "+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!
- } // using this instead would not work: subst.map { p => Ident(p._2) }
- // the order can be garbled, when default patterns are used... #bug 1163
-
- val body = Apply(Ident(theLabel), args)
- return body
-
- case None =>
- // 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)
-
- var nbody: Tree = b
- val vrefs = vdefs.map { p:ValDef => Ident(p.symbol) }
- nbody = squeezedBlock(vdefs:::List(Apply(Ident(theLabel), vrefs)), LabelDef(theLabel, subst.map(_._1), nbody))
- bodies(b) = (EmptyTree, nbody, theLabel)
- nbody
+ final def genBody(subst: List[Pair[Symbol,Symbol]], origbody:Tree)(implicit theOwner: Symbol, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = {
+ origbody match {
+ case _: Literal => // small trees
+ bodies(origbody) = null // placeholder, for unreachable-code-detection
+ val res = typed{ origbody.duplicate }
+ return res
+ case _: Throw =>
+ bodies(origbody) = null // placeholder, for unreachable-code-detection
+ val (from,to) = List.unzip(subst)
+ val b2 = origbody.duplicate
+ new TreeSymSubstituter(from,to).traverse(b2)
+ val res = typed{ b2 }
+ return res
+ case _:Ident =>
+ bodies(origbody) = null // placeholder, for unreachable-code-detection
+ val bsym = origbody.symbol
+ var su = subst // lookup symbol in pattern variables
+ while(su ne Nil) {
+ val sh = su.head;
+ if(sh._1 eq bsym) return typed{ Ident(sh._2) }
+ su = su.tail
+ }
+ val res = typed{ origbody.duplicate }
+ return res
+
+ case _ =>
+ bodies.get(origbody) match {
+
+ case Some(EmptyTree, nb, theLabel) => //Console.println("H E L L O"+subst+" "+b)
+ // recover the order of the idents that is expected for the labeldef
+ val args = (nb: @unchecked) match {
+ case LabelDef(_, Nil, _) =>
+ // nothing to do
+ Nil
+ case Block(_, LabelDef(_, origs, _)) =>
+ origs.map { p => typed{Ident(subst.find { q => q._1 == p.symbol }.get._2)}} // wrong!
+ } // using this instead would not work: subst.map { p => Ident(p._2) }
+ // the order can be garbled, when default patterns are used... #bug 1163
+ val body = Apply(Ident(theLabel), args)
+ return typed{body}
+
+ case None =>
+ // sharing bodies
+ var argtpes = subst map { case (v,_) => v.tpe }
+ val theLabel = targetLabel(theOwner, origbody.pos, "body"+origbody.hashCode, argtpes, origbody.tpe)
+ // make new value parameter for each vsym in subst
+
+ var nbody: Tree = if(subst.isEmpty)
+ LabelDef(theLabel, Nil, origbody)
+ else {
+ val vdefs = targetParams(subst)
+ val vrefs = vdefs.map { p:ValDef => Ident(p.symbol) }
+ squeezedBlock(vdefs:::List(Apply(Ident(theLabel), vrefs)),
+ LabelDef(theLabel, subst.map(_._1), origbody))
+ }
+ bodies(origbody) = (EmptyTree, nbody, theLabel)
+ return nbody
+ }
}
}
+
/** converts given rep to a tree - performs recursive call to translation in the process to get sub reps
*/
final def repToTree(rep:Rep, handleOuter: Tree => Tree)(implicit theOwner: Symbol, failTree: Tree, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = {
@@ -759,7 +777,7 @@ trait ParallelMatching {
//Console.println("getTransition"+(uacall,vdefs,srep,frep))
val succ = repToTree(srep, handleOuter)
val fail = if(frep.isEmpty) failTree else repToTree(frep.get, handleOuter)
- val cond = if(uacall.symbol.tpe./*?type?*/symbol eq definitions.BooleanClass)
+ val cond = if(uacall.symbol.tpe.typeSymbol eq definitions.BooleanClass)
typed{ Ident(uacall.symbol) }
else
emptynessCheck(uacall.symbol)
@@ -775,7 +793,10 @@ object Rep {
if(x.isInstanceOf[RepImpl]) Some(x.asInstanceOf[RepImpl]) else None
private case class RepImpl(val temp:List[Symbol], val row:List[Row]) extends Rep with RepType {
- assert(row.forall { case Row(pats,subst,g,b) => temp.length == pats.length });
+ (row.find { case Row(pats,subst,g,b) => temp.length != pats.length }) match {
+ case Some(row) => assert(false, "temp == "+temp+" row.pats == "+row.pat);
+ case _ =>
+ }
def _1 = temp
def _2 = row
}
@@ -820,7 +841,7 @@ object Rep {
//Console.println("/'''''''''''' 5"+o.symbol.tpe.prefix.isStable)
val stpe =
- if (o.tpe./*?term?*/symbol.isModule)
+ if (o.tpe./*term?*/symbol.isModule)
singleType(o.tpe.prefix, o.symbol)
else
singleType(NoPrefix, o.symbol)
@@ -840,6 +861,8 @@ object Rep {
/** something too tricky is going on if the outer types don't match
*/
case o @ Apply(app, List()) if !isCaseClass(o.tpe) =>
+ System.out.println("this should not happen (experimental code)")
+ throw new RuntimeException("non-case apply encountered in parallelmatching")
//Console.println(o)
//val stpe = singleType(NoPrefix, o.symbol)
val stpe =
@@ -900,7 +923,7 @@ object Rep {
val z = candidates(x)
if(x.hasFlag(symtab.Flags.ABSTRACT)) z else z + x
}
- val cases = candidates(sym.tpe./*?type?*/symbol)
+ val cases = candidates(sym.tpe.typeSymbol)
sealedComb = cases::sealedComb
}
}
@@ -933,7 +956,7 @@ object Rep {
singleType(sym.tpe.prefix, sym.linkedModuleOfClass) // e.g. None, Nil
} else sym.tpe
//Console.print("covers: sym="+sym+" symtpe="+symtpe+" p="+p+", p.tpe="+p.tpe+" ?")
- (p.tpe./*?type?*/symbol == sym) || (symtpe <:< p.tpe) ||
+ (p.tpe.typeSymbol == sym) || (symtpe <:< p.tpe) ||
/* outer, see scala.util.parsing.combinator.lexical.Scanner */
(p.tpe.prefix.memberType(sym) <:< p.tpe)
}
@@ -1035,29 +1058,7 @@ object Rep {
// case Typed(nme.WILDCARD,_) => pattern.tpe <:< scrutinee.tpe
}
- /** returns all variables that are binding the given pattern
- * @param x a pattern
- * @return vs variables bound, p pattern proper
- */
- final def strip(x: Tree): (Set[Symbol], Tree) = x match {
- case b @ Bind(_,pat) => val (vs, p) = strip(pat); (vs + b.symbol, p)
- case z => (emptySymbolSet, z)
- }
-
- final def strip1(x:Tree): Set[Symbol] = x match { // same as strip(x)._1
- case b @ Bind(_,pat) => strip1(pat) + b.symbol
- case z => emptySymbolSet
- }
- final def strip2(x:Tree): Tree = x match { // same as strip(x)._2
- case Bind(_,pat) => strip2(pat)
- case z => z
- }
-
- // ---------------------------------- functions used in internal data structure of the algorithm (matrix)
-
-
// ---------------------------------- helper functions that generate symbols, trees for type tests, pattern tests
- // (shared by both algorithms, cough)
final def newVar(pos: Position, name: Name, tpe: Type)(implicit theOwner: Symbol): Symbol = {
if(tpe eq null) assert(tpe ne null, "newVar("+name+", null)")
@@ -1093,11 +1094,11 @@ object Rep {
//Console.println("module "+tpe./*?term?*/symbol.isModule)
if (tpe.isInstanceOf[SingletonType] && !tpe.isInstanceOf[ConstantType]) {
- if (tpe./*?term?*/symbol.isModule) {// object
+ if (tpe.termSymbol.isModule) {// object
if (scrutineeTree.tpe <:< definitions.AnyRefClass.tpe)
- Eq(gen.mkAttributedRef(tpe./*?term?*/symbol), scrutineeTree) // object
+ Eq(gen.mkAttributedRef(tpe.termSymbol), scrutineeTree) // object
else
- Equals(gen.mkAttributedRef(tpe./*?term?*/symbol), scrutineeTree) // object
+ Equals(gen.mkAttributedRef(tpe.termSymbol), scrutineeTree) // object
} else {
//Console.print("111 ??")
//Console.println("tpe stable "+tpe.isStable)
@@ -1105,7 +1106,7 @@ object Rep {
//val x = Equals(Apply(gen.mkAttributedRef(tpe./*?term?*/symbol), List()), scrutineeTree)
val x =
if(tpe.prefix ne NoPrefix) gen.mkIsInstanceOf(scrutineeTree, tpe)
- else Equals(gen.mkAttributedRef(tpe./*?term?*/symbol), scrutineeTree)
+ else Equals(gen.mkAttributedRef(tpe.termSymbol), scrutineeTree)
//Console.println(" = "+x)
typed { x }
}
@@ -1135,8 +1136,8 @@ object Rep {
final def needsOuterTest(tpe2test: Type, scrutinee: Type) = tpe2test.normalize match {
case TypeRef(prefix,_,_) =>
- prefix./*?term?*/symbol.isTerm &&
- !prefix./*?term?*/symbol.isPackage &&
+ prefix.termSymbol.isTerm &&
+ !prefix.termSymbol.isPackage &&
outerAlwaysEqual(tpe2test, scrutinee) == Some(false)
case _ =>
false
@@ -1159,14 +1160,14 @@ object Rep {
/** adds a test comparing the dynamic outer to the static outer */
final def addOuterCondition(cond:Tree, tpe2test: Type, scrutinee: Tree, handleOuter: Tree=>Tree) = {
val TypeRef(prefix,_,_) = tpe2test
- var theRef = gen.mkAttributedRef(prefix.prefix, prefix./*?term?*/symbol)
+ var theRef = gen.mkAttributedRef(prefix.prefix, prefix.termSymbol)
// needs explicitouter treatment
theRef = handleOuter(theRef)
- val outerAcc = outerAccessor(tpe2test./*?type?*/symbol)
+ val outerAcc = outerAccessor(tpe2test.typeSymbol)
if (outerAcc == NoSymbol) {
- if (settings_debug) cunit.warning(scrutinee.pos, "no outer acc for "+tpe2test./*?type?*/symbol)
+ if (settings_debug) cunit.warning(scrutinee.pos, "no outer acc for "+tpe2test.typeSymbol)
cond
} else
And(cond,
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index e85671dd40..281e45ed56 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -199,7 +199,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
resetTrav.traverse(dfatree)
//constructParallel(cases) // ZZZ
- nParallel = nParallel + 1
+ nParallel += 1
return null
} catch {
case e => return e // fallback
@@ -502,9 +502,6 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
enter1(pat, index, target, casted, env)
}
- type SelectorMap = collection.mutable.HashMap[(Symbol,Symbol),List[Symbol]]
- val selectorMap = new SelectorMap
-
private def newHeader(pos: Position, casted: Symbol, index: Int): Header = {
//Console.println("newHeader(pos,"+casted+" (has CASE flag? "+casted.tpe.symbol.hasFlag(Flags.CASE)+") of type "+casted.tpe+" with pos "+casted.pos+"(equals FIRSTPOS? "+(casted.pos == Position.FIRSTPOS)+"),"+index+")");
val ident = typed(Ident(casted))
@@ -524,7 +521,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par
//Console.println("getProductArgs? "+defs.getProductArgs(casted.tpe));
defs.getProductArgs(casted.tpe) match {
case Some(targs) =>
- val accSym = defs.productProj(casted.tpe./*?type?*/symbol, index+1)
+ val accSym = defs.productProj(casted.tpe.typeSymbol, index+1)
val accTree = typed(Apply(Select(ident, accSym), List())) // nsc !
return pHeader(pos, accTree.tpe, accTree)
case None =>
@@ -543,8 +540,8 @@ print()
//Console.println("CASE");
- val caseAccs = casted.tpe./*?type?*/symbol.caseFieldAccessors;
- if (caseAccs.length <= index) Console.println("selecting " + index + " in case fields of " + casted.tpe./*?type?*/symbol + "=" + casted.tpe./*?type?*/symbol.caseFieldAccessors);//debug
+ val caseAccs = casted.tpe.typeSymbol.caseFieldAccessors;
+ if (caseAccs.length <= index) Console.println("selecting " + index + " in case fields of " + casted.tpe.typeSymbol + "=" + caseAccs);//debug
val ts = caseAccs(index);
val accTree = typed(Apply(Select(ident, ts), List()))
val accType = accTree.tpe
@@ -623,13 +620,6 @@ print()
target.and = curHeader; // (*)
//Console.println("curHeader : "+curHeader)
-/* first try at exhaust improvement
- selectorMap.update((casted, curHeader.selector.symbol),
- selectorMap.get(casted, curHeader.selector.symbol) match {
- case Some(xs) => pat.tpe./*?type?*/symbol::xs
- case _ => pat.tpe./*?type?*/symbol::Nil
- })
-*/
if (bodycond ne null) target.and = bodycond(target.and) // restores body with the guards
curHeader.or = patternNode(pat, curHeader, env)
@@ -711,7 +701,7 @@ print()
protected def nCaseComponents(tree: Tree): int = {
tree match {
case Apply(fn, _) =>
- val tpe = tree.tpe./*?type?*/symbol.primaryConstructor.tpe
+ val tpe = tree.tpe.typeSymbol.primaryConstructor.tpe
//Console.println("~~~ " + tree.type() + ", " + tree.type().symbol.primaryConstructor());
tpe match {
// I'm not sure if this is a good idea, but obviously, currently all case classes
@@ -1148,7 +1138,7 @@ print()
case DefaultPat() =>
return toTree(node.and);
- case UnapplyPat(casted, Apply(fn1, appargs)) if casted.tpe./*?type?*/symbol == defs.BooleanClass => // special case
+ case UnapplyPat(casted, Apply(fn1, appargs)) if casted.tpe.typeSymbol == defs.BooleanClass => // special case
var useSelector = selector
val checkType = fn1.tpe match {
case MethodType(List(argtpe,_*),_) =>
@@ -1211,25 +1201,10 @@ print()
// compare outer instance for patterns like foo1.Bar foo2.Bar if not statically known to match
casted.tpe match {
case TypeRef(prefix,_,_) if needsOuterTest(casted.tpe, selector.tpe) =>
-
//@attention, deep typer bug: if we omit "typed" here, we crash when typing the tree that contains this fragment
cond = typed{ addOuterCondition(cond, casted.tpe, selector.duplicate, handleOuter) }
- /*
- var theRef = gen.mkAttributedRef(prefix.prefix, prefix.symbol)
- // needs explicitouter treatment
- theRef = handleOuter(theRef)
-
- val outerAcc = outerAccessor(casted.tpe./*?type?*/symbol)
-
- if(outerAcc != NoSymbol) { // some guys don't have outers
- cond = And(cond,
- Eq(Apply(Select(
- typed(gen.mkAsInstanceOf(selector.duplicate, ntpe, true)), outerAcc),List()), theRef))
- }
- */
- case _ =>
- //ignore ;
+ case _ => //ignore ;
}
val cast_untyped = gen.mkAsInstanceOf(selector.duplicate, ntpe, true)
diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
index 56bd401a46..4fc3db664f 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
@@ -15,6 +15,26 @@ trait PatternNodes { self: transform.ExplicitOuter =>
import global._
+ /** returns all variables that are binding the given pattern
+ * @param x a pattern
+ * @return vs variables bound, p pattern proper
+ */
+ final def strip(x: Tree): (Set[Symbol], Tree) = x match {
+ case b @ Bind(_,pat) => val (vs, p) = strip(pat); (vs + b.symbol, p)
+ case z => (emptySymbolSet,z)
+ }
+
+ final def strip1(x: Tree): Set[Symbol] = x match { // same as strip(x)._1
+ case b @ Bind(_,pat) => strip1(pat) + b.symbol
+ case z => emptySymbolSet
+ }
+ final def strip2(x: Tree): Tree = x match { // same as strip(x)._2
+ case Bind(_,pat) => strip2(pat)
+ case z => z
+ }
+
+ //
+
type SymSet = collection.immutable.Set[Symbol]
/** returns the child patterns of a pattern
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index ce5a62aff1..d5fd594c2f 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -62,6 +62,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
tp match {
case ConstantType(_) =>
tp
+ case NotNullType(tp) => // BQ to Martin: this used to be below st:SubType and unreachable, moved up
+ apply(tp)
case st: SubType =>
apply(st.supertype)
case TypeRef(pre, sym, args) =>
@@ -96,8 +98,6 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
else if (clazz == ArrayClass) List(erasedTypeRef(ObjectClass))
else removeDoubleObject(parents map this),
decls, clazz)
- case NotNullType(tp) =>
- apply(tp)
case _ =>
mapOver(tp)
}