diff options
author | Burak Emir <emir@epfl.ch> | 2007-07-25 02:01:33 +0000 |
---|---|---|
committer | Burak Emir <emir@epfl.ch> | 2007-07-25 02:01:33 +0000 |
commit | a64786e441954e1b4fd9bf8731949117763c24d6 (patch) | |
tree | 6b80b382e439012ddfc13df914bba0c63a2464a5 | |
parent | d6f27a8d9ca9b0207e85a594cc6c36588c346240 (diff) | |
download | scala-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 (*)
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) } |