From 96f6c893f1ad84ef81e975820af566a926a246c3 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 29 Jun 2009 20:13:33 +0000 Subject: Working on the pattern matcher. in the parts I mostly understand to terms more evocative than e.g. "strip2". --- src/compiler/scala/tools/nsc/ast/TreeDSL.scala | 6 ++ .../scala/tools/nsc/matching/CodeFactory.scala | 28 +++---- .../tools/nsc/matching/ParallelMatching.scala | 85 +++++++++++----------- .../scala/tools/nsc/matching/PatternNodes.scala | 45 ++++++++---- .../scala/tools/nsc/matching/TransMatcher.scala | 9 ++- .../scala/tools/nsc/transform/ExplicitOuter.scala | 14 +++- 6 files changed, 105 insertions(+), 82 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala index 09fc7ff2a9..e54bdab529 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala @@ -62,6 +62,7 @@ trait TreeDSL { def ANY_NE (other: Tree) = fn(target, nme.ne, toAnyRef(other)) def ANY_EQ (other: Tree) = fn(target, nme.eq, toAnyRef(other)) def ANY_== (other: Tree) = fn(target, Any_==, other) + def ANY_>= (other: Tree) = fn(target, nme.GE, other) def OBJ_!= (other: Tree) = fn(target, Object_ne, other) def INT_| (other: Tree) = fn(target, getMember(IntClass, nme.OR), other) @@ -82,6 +83,11 @@ trait TreeDSL { /** Assignment */ def ===(rhs: Tree) = Assign(target, rhs) + /** for tree of sequence type, returns tree that drops first i elements */ + def DROP(count: Int): Tree = + if (count == 0) target + else (target DOT nme.drop)(LIT(count)) DOT nme.toSeq + /** Casting & type tests -- working our way toward understanding exactly * what differs between the different forms of IS and AS. */ diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala index 021adfe3aa..c7c2db3cc7 100644 --- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala +++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala @@ -34,28 +34,22 @@ trait CodeFactory extends ast.TreeDSL } /** for tree of sequence type, returns tree that drops first i elements */ - final def seqDrop(sel:Tree, ix: Int)(implicit typer : Typer) = - if (ix == 0) sel else - typer typed (fn(sel, nme.drop, LIT(ix)) DOT nme.toSeq) + final def seqDrop(sel: Tree, ix: Int)(implicit typer : Typer) = + typer typed (sel DROP ix) /** for tree of sequence type, returns tree that represents element at index i */ - final def seqElement(sel:Tree, ix: Int)(implicit typer : Typer) = - typer typed (fn(sel, sel.tpe.member(nme.apply), LIT(ix))) + final def seqElement(sel: Tree, ix: Int)(implicit typer : Typer) = + typer typed ((sel DOT (sel.tpe member nme.apply))(LIT(ix))) + + private def lengthCompare(sel: Tree, tpe: Type, i: Int) = ((sel DOT tpe.member(nme.lengthCompare))(LIT(i))) /** for tree of sequence type, returns boolean tree testing that the sequence has length i */ - final def seqHasLength(sel: Tree, ntpe: Type, i: Int)(implicit typer : Typer) = - typer typed (fn(sel, ntpe.member(nme.lengthCompare), LIT(i)) ANY_== ZERO) // defs.Seq_length ? - - /** for tree of sequence type sel, returns boolean tree testing that length >= i - */ - final def seqLongerThan(sel:Tree, tpe:Type, i:Int)(implicit typer : Typer) = { - val cmp = fn(sel, tpe.member(nme.lengthCompare), LIT(i)) - GTE(typer.typed(cmp), typer.typed(ZERO)) // defs.Seq_length instead of tpe.member? - } + final def seqHasLength(sel: Tree, tpe: Type, i: Int)(implicit typer : Typer) = + typer typed (lengthCompare(sel, tpe, i) ANY_== ZERO) - final def GTE (left: Tree, right: Tree): Tree = fn(left, nme.GE, right) // >= - final def ThrowMatchError(pos: Position, obj: Tree) = atPos(pos)(THROW(MatchErrorClass, obj)) - final def Get(tree: Tree) = fn(tree, nme.get) + /** for tree of sequence type sel, returns boolean tree testing that length >= i */ + final def seqLongerThan(sel:Tree, tpe:Type, i:Int)(implicit typer : Typer) = + typer typed (lengthCompare(sel, tpe, i) ANY_>= ZERO) final def squeezedBlock(vds: List[Tree], exp: Tree)(implicit theOwner: Symbol): Tree = if (settings_squeeze) Block(Nil, squeezedBlock1(vds, exp)) diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 9e18d94d97..14f6f5fd75 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -39,6 +39,11 @@ trait ParallelMatching extends ast.TreeDSL { import Types._ import CODE._ + object Implicits { + implicit def mkPattern(t: Tree) = Pattern(t) + } + import Implicits._ + /** * Encapsulates a symbol being matched on. * @@ -76,13 +81,11 @@ trait ParallelMatching extends ast.TreeDSL { } case class Pattern(tree: Tree) { - implicit def mkPattern(t: Tree) = Pattern(t) import definitions._ lazy val sym = tree.symbol lazy val tpe = tree.tpe lazy val symtpe = sym.tpe lazy val prefix = tpe.prefix - lazy val stripped = strip2 lazy val tpeIfHead = stripped.tree match { case p @ (_:Ident | _:Select) => singleType(stripped.prefix, stripped.sym) //should be singleton object case __UnApply(_,argtpe,_) => argtpe @@ -123,16 +126,18 @@ trait ParallelMatching extends ast.TreeDSL { get_BIND(x => x, tree) } - /** returns all variables that are binding the given pattern - * @param x a pattern - * @return vs variables bound, p pattern proper - */ - final def strip: (immutable.Set[Symbol], Pattern) = tree match { - case b @ Bind(_, t) => val (vs, p) = Pattern(t).strip ; (vs + b.symbol, p) - case _ => (emptySymbolSet, this) + // XXX move right place + def allBindings: List[Bind] = allBindingsInt(tree) + private def allBindingsInt(t: Tree): List[Bind] = t match { + case b @ Bind(_, t) => b :: allBindingsInt(t) + case _ => Nil } - final def strip1: Set[Symbol] = strip._1 - final def strip2: Pattern = strip._2 + + /** All variables binding the given pattern. */ + def boundVariables: List[Symbol] = allBindings.foldRight(List[Symbol]())(_.symbol :: _) + + /** The pattern with its variable bindings stripped. */ + def stripped: Tree = if (allBindings.isEmpty) tree else allBindings.last.body final def definedVars: List[Symbol] = ParallelMatching.this.definedVars(tree) @@ -186,7 +191,8 @@ trait ParallelMatching extends ast.TreeDSL { def isEmpty = tree eq EmptyTree def duplicate = Guard(tree.duplicate) - def mkIf(thenPart: Tree, elsePart: Tree) = If(tree.duplicate, thenPart, elsePart) + def mkIf(thenPart: Tree, elsePart: Tree) = + IF (tree.duplicate) THEN thenPart ELSE elsePart } val NoGuard = Guard(EmptyTree) @@ -236,7 +242,7 @@ trait ParallelMatching extends ast.TreeDSL { var defaultV: immutable.Set[Symbol] = emptySymbolSet var defaultIndexSet = new BitSet(pats.size) - def insertDefault(tag: Int, vs: Set[Symbol]) { + def insertDefault(tag: Int, vs: Traversable[Symbol]) { defaultIndexSet += tag defaultV = defaultV ++ vs } @@ -248,7 +254,7 @@ trait ParallelMatching extends ast.TreeDSL { protected def grabRow(index: Int): Row = { val r = rest.row(index) if (defaultV.isEmpty) r - else r.insert2(Nil, strip1(pats(index)), scrut.sym) // get vars + else r.insert2(Nil, pats(index).boundVariables, scrut.sym) // get vars } /** inserts row indices using in to list of tagIndices */ @@ -268,14 +274,13 @@ trait ParallelMatching extends ast.TreeDSL { def getTransition(implicit theOwner: Symbol): (List[(Int,Rep)], Set[Symbol], Option[Rep]) = (tagIndicesToReps, defaultV, if (haveDefault) Some(defaultsToRep) else None) - val Patterns(scrut, patterns) = pats val varMap: List[(Int, List[Symbol])] = - (for ((x, i) <- pats.zip) yield strip2(x) match { - case p @ LIT(c: Int) => insertTagIndexPair(c, i) ; Some(c, definedVars(x)) - case p @ LIT(c: Char) => insertTagIndexPair(c.toInt, i) ; Some(c.toInt, definedVars(x)) - case p if isDefaultPattern(p) => insertDefault(i, strip1(x)) ; None + (for ((x, i) <- pats.zip) yield x.stripped match { + case p @ LIT(c: Int) => insertTagIndexPair(c, i) ; Some(c, definedVars(x)) + case p @ LIT(c: Char) => insertTagIndexPair(c.toInt, i) ; Some(c.toInt, definedVars(x)) + case p if isDefaultPattern(p) => insertDefault(i, x.boundVariables) ; None }) . flatMap(x => x) . reverse // lazy @@ -300,8 +305,9 @@ trait ParallelMatching extends ast.TreeDSL { cases match { case CaseDef(lit,_,body) :: Nil => IF (scrut.id ANY_== lit) THEN body ELSE ndefault - case _ if scrut.isChar => Match(Select(scrut.id, nme.toInt), casesWithDefault) // chars to ints - case _ => Match(scrut.id, casesWithDefault) + case _ => + val target: Tree = if (scrut.isChar) scrut.id DOT nme.toInt else scrut.id // chars to ints + target MATCH (casesWithDefault: _*) } } } @@ -331,7 +337,7 @@ trait ParallelMatching extends ast.TreeDSL { val uacall = typedValDef(ures, rhs) val zipped = pats.zip(rest.row) val nrowsOther = zipped.tail flatMap - { case (Strip2(sameUnapplyCall(_)), _) => Nil ; case (pat, r) => List(r.insert(pat)) } + { case (Stripped(sameUnapplyCall(_)), _) => Nil ; case (pat, r) => List(r.insert(pat)) } val nrepFail = if (nrowsOther.isEmpty) None @@ -355,12 +361,12 @@ trait ParallelMatching extends ast.TreeDSL { val vtpe = app.tpe.typeArgs(0) val vsym = newVarCapture(ua.pos, vtpe) val nrows = mkNewRows((xs) => List(xs.head), 1) - val vdef = typedValDef(vsym, Get(ID(ures))) + val vdef = typedValDef(vsym, fn(ID(ures), nme.get)) mkTransition(List(vdef), List(vsym), nrows) case _ => // app.tpe is Option[? <: ProductN[T1,...,Tn]] val uresGet = newVarCapture(ua.pos, app.tpe.typeArgs(0)) - val vdefHead = typedValDef(uresGet, Get(ID(ures))) + val vdefHead = typedValDef(uresGet, fn(ID(ures), nme.get)) val ts = definitions.getProductArgs(uresGet.tpe).get val nrows = mkNewRows(identity, ts.size) val (vdefs: List[Tree], vsyms: List[Symbol]) = List.unzip( @@ -396,7 +402,7 @@ trait ParallelMatching extends ast.TreeDSL { val Patterns(scrut, patterns) = pats final def removeStar(xs: List[Tree]): List[Tree] = - xs.init ::: makeBind(strip1(xs.last).toList, WILD(scrut.sequenceType)) :: Nil + xs.init ::: makeBind(xs.last.boundVariables, WILD(scrut.sequenceType)) :: Nil protected def getSubPatterns(len:Int, x:Tree):Option[List[Tree]] = x match { case av @ ArrayValue(_,xs) if (!isRightIgnoring(av) && xs.length == len) => Some(xs ::: List(EmptyTree)) @@ -427,7 +433,7 @@ trait ParallelMatching extends ast.TreeDSL { val treeAsSeq = scrut.id // scrut.tpe <:< column.head.tpe confirmed by assertion val av @ ArrayValue(_, xs) = pats.head.tree val ys = if (isRightIgnoring(av)) xs.init else xs - val vs = ys map(y => newVar(strip2(y).pos, scrut.elementType)) + val vs = ys map (y => newVar(y.stripped.pos, scrut.elementType)) lazy val tail = newVar(scrut.pos, scrut.sequenceType) lazy val lastBinding = if (ys.size > 0) seqDrop(treeAsSeq.duplicate, ys.size) else scrut.id @@ -496,7 +502,7 @@ trait ParallelMatching extends ast.TreeDSL { case TypeRef(_,_,List(PseudoType(o))) => o.duplicate } assert(vlue.tpe ne null, "value tpe is null") - val vs = head.strip1.toList + val vs = head.boundVariables val nsuccFst = rest.row.head.insert2(List(EmptyTree), vs, scrut.sym) val fLabel = theOwner.newLabel(scrut.pos, cunit.fresh.newName(scrut.pos, "failCont%")) // warning, untyped val sx = rep.shortCut(fLabel) // register shortcut @@ -536,7 +542,7 @@ trait ParallelMatching extends ast.TreeDSL { // remaining: remaining, row index and pattern def join[T](xs: List[Option[T]]): List[T] = xs.flatMap(x => x) val (moreSpecific, subsumed, remaining) : (List[Tree], List[(Int, List[Tree])], List[(Int, Tree)]) = unzip3( - for ((pat @ Strip2(spat), j) <- pats.zip) yield { + for ((pat @ Stripped(spat), j) <- pats.zip) yield { def eqHead(tpe: Type) = pats.headType =:= tpe def alts(yes: Tree, no: Tree) = if (eqHead(pat.tpe)) yes else no @@ -554,7 +560,7 @@ trait ParallelMatching extends ast.TreeDSL { (spat match { case LIT(null) if !eqHead(spat.tpe) => (None, None, pass) // special case for constant null case _ if pats.isObjectTest(pat) => (EmptyTree, dummy, None) // matching an object - case Typed(p @ Strip2(_: UnApply), _) if xIsaY => (p, dummy, None) // <:< is never + case Typed(p @ Stripped(_: UnApply), _) if xIsaY => (p, dummy, None) // <:< is never case q @ Typed(pp, _) if xIsaY => (alts(pp, q), dummy, None) // never =:= for case z: UnApply => (None, None, pass) case _ if erased.xIsaY || xIsaY && !isDef => (alts(EmptyTree, pat), subs, None) // never =:= for @@ -636,10 +642,10 @@ trait ParallelMatching extends ast.TreeDSL { * @param comb pairs of (column index, type symbol) */ def covers(comb: List[(Int, Symbol)]) = { - lazy val results = for ((i, sym) <- comb ; val p = strip2(pat(i))) yield p match { + lazy val results = for ((i, sym) <- comb ; val p = pat(i).stripped) yield p match { case _ if isDefaultPattern(p) => true case _: UnApply | _: ArrayValue => true - case _ => p.tpe.coversSym(sym) + case _ => p.tpe coversSym sym } guard.isEmpty && results.forall(_ == true) @@ -662,8 +668,8 @@ trait ParallelMatching extends ast.TreeDSL { val indexOfAlternative = pat findIndexOf isAlternative val pats: List[Tree] = List.map2(pat, pat.indices.toList)(classifyPat) - lazy val (prefix, alts :: suffix) = pats.splitAt(indexOfAlternative) - lazy val alternativeBranches = getAlternativeBranches(alts) map { p => replace(prefix ::: p :: suffix) } + lazy val (prefix, alts :: suffix) = pats splitAt indexOfAlternative + lazy val alternativeBranches = getAlternativeBranches(alts) map (x => replace(prefix ::: x :: suffix)) if (indexOfAlternative == -1) List(replace(pats)) else alternativeBranches } @@ -818,7 +824,7 @@ trait ParallelMatching extends ast.TreeDSL { strippedPat match { case _: Alternative => opat - case Typed(p @ Strip2(_: UnApply), tpt) => if (temp(j).tpe <:< tpt.tpe) makeBind(vs, p) + case Typed(p @ Stripped(_: UnApply), tpt) => if (temp(j).tpe <:< tpt.tpe) makeBind(vs, p) else opat // case Ident_Or_Empty() => opat // this doesn't work - see notes in PatternNode case Ident(nme.WILDCARD) | EmptyTree => opat @@ -838,8 +844,7 @@ trait ParallelMatching extends ast.TreeDSL { val ttst = mkEqualsRef(List(stpe)) makeBind(vs, Typed(WILD(ttst), TypeTree(stpe)) setType ttst) case Apply_Value(pre, sym) => mkEmptyTreeBind(vs, mkEqualsRef(List(singleType(pre, sym)))) - case Apply_CaseClass_NoArgs(tpe) => mkEmptyTreeBind(vs, tpe) - case Apply_CaseClass_WithArgs() => opat + case Apply_CaseClass(tpe, args) => if (args.isEmpty) mkEmptyTreeBind(vs, tpe) else opat case _: ArrayValue => opat case x => throw new Exception("Unexpected pattern: " + x.getClass + " => " + x) } @@ -880,7 +885,7 @@ trait ParallelMatching extends ast.TreeDSL { case (i,syms)::cs => for (s <- syms.toList; rest <- combine(cs)) yield (i,s) :: rest } - private def comboCovers(combo: List[(Int, Symbol)]) = row exists { r => r.covers(combo) } + private def comboCovers(combo: List[(Int, Symbol)]) = row exists (_ covers combo) def init: this.type = { val allcomb = combine(setsToCombine) @@ -894,11 +899,7 @@ trait ParallelMatching extends ast.TreeDSL { def mkMissingStr(open: List[(Int, Symbol)]) = "missing combination " + temp.indices.map(mkPad(open, _)).mkString + "\n" - val missingCombos = allcomb - . filter(open => row.forall(!_.covers(open))) - . map(mkMissingStr) - . mkString - + val missingCombos = (allcomb filter (open => row.forall(!_.covers(open))) map mkMissingStr).mkString cunit.warning(temp.head.pos, "match is not exhaustive!\n" + missingCombos) this } diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala index befb8b8926..d25dfb0143 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala @@ -121,9 +121,9 @@ trait PatternNodes extends ast.TreeDSL def mkEqualsRef(xs: List[Type]) = typeRef(NoPrefix, definitions.EqualsPatternClass, xs) def normalizedListPattern(pats:List[Tree], tptArg:Type): Tree = pats match { - case Nil => gen.mkNil - case (sp @ Strip(_, _: Star)) :: xs => makeBind(definedVars(sp), WILD(sp.tpe)) - case x::xs => + case Nil => gen.mkNil + case (sp @ Strip(_, _: Star)) :: _ => makeBind(definedVars(sp), WILD(sp.tpe)) + case x :: xs => var resType: Type = null; val consType: Type = definitions.ConsClass.primaryConstructor.tpe match { case mt @ MethodType(args, res @ TypeRef(pre,sym,origArgs)) => @@ -133,23 +133,33 @@ trait PatternNodes extends ast.TreeDSL val dummyMethod = new TermSymbol(NoSymbol, NoPosition, "matching$dummy") MethodType(dummyMethod.newSyntheticValueParams(List(tptArg, listType)), resType) } - Apply(TypeTree(consType), List(x,normalizedListPattern(xs,tptArg))) setType resType + Apply(TypeTree(consType), List(x, normalizedListPattern(xs, tptArg))) setType resType } + // if Apply target !isType and takes no args, returns target prefix and symbol object Apply_Value { - def unapply(x: Apply) = if (!x.fun.isType && x.args.isEmpty) Some(x.tpe.prefix, x.symbol) else None + def unapply(x: Any) = x match { + case x @ Apply(fun, args) if !fun.isType && args.isEmpty => Some(x.tpe.prefix, x.symbol) + case _ => None + } } + // if Apply tpe !isCaseClass and Apply_Value says false, return the Apply target object Apply_Function { - def isApplyFunction(o: Apply) = !o.tpe.isCaseClass || !Apply_Value.unapply(o).isEmpty /*see t301*/ - def unapply(x: Apply) = if (x.args.isEmpty && isApplyFunction(x)) Some(x.fun) else None + /* see t301 */ + def isApplyFunction(o: Apply) = !o.tpe.isCaseClass || !Apply_Value.unapply(o).isEmpty + def unapply(x: Any) = x match { + case x @ Apply(fun, Nil) if isApplyFunction(x) => Some(fun) + case _ => None + } } - object Apply_CaseClass_NoArgs { - def unapply(x: Apply) = if (x.fun.isType && x.args.isEmpty) Some(x.tpe) else None - } - object Apply_CaseClass_WithArgs { - def unapply(x: Apply) = x.fun.isType + // if Apply target isType (? what does this imply exactly) returns type and arguments. + object Apply_CaseClass { + def unapply(x: Any) = x match { + case x @ Apply(fun, args) if fun.isType => Some(x.tpe, args) + case _ => None + } } // TODO - this doesn't work! For some reason this sometimes returns false when encapsulated @@ -202,12 +212,15 @@ trait PatternNodes extends ast.TreeDSL case b @ Bind(_,pat) => val (vs, p) = strip(pat); (vs + b.symbol, p) case _ => (emptySymbolSet, x) } - final def strip1(x: Tree): Set[Symbol] = strip(x)._1 - final def strip2(x: Tree): Tree = strip(x)._2; object Strip { def unapply(x: Tree): Option[(Set[Symbol], Tree)] = Some(strip(x)) } - object Strip1 { def unapply(x: Tree): Option[Set[Symbol]] = Some(strip1(x)) } - object Strip2 { def unapply(x: Tree): Option[Tree] = Some(strip2(x)) } + + object BoundVariables { + def unapply(x: Tree): Option[List[Symbol]] = Some(Pattern(x).boundVariables) + } + object Stripped { + def unapply(x: Tree): Option[Tree] = Some(Pattern(x).stripped) + } final def definedVars(x: Tree): List[Symbol] = { implicit def listToStream[T](xs: List[T]): Stream[T] = xs.toStream diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala index 7525cedbe3..057c072481 100644 --- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala +++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala @@ -50,6 +50,7 @@ trait TransMatcher extends ast.TreeDSL { implicit val rep = new RepFactory(handleOuter) val flags = if (doCheckExhaustive) Nil else List(Flags.TRANS_FLAG) + def matchError(obj: Tree) = atPos(selector.pos)(THROW(MatchErrorClass, obj)) def caseIsOk(c: CaseDef) = c match { case CaseDef(_: Apply, _, _) => true case CaseDef(Ident(nme.WILDCARD), _, _) => true @@ -69,7 +70,7 @@ trait TransMatcher extends ast.TreeDSL { (v, typedValDef(v, ti)) } ) - (tmps, vds, ThrowMatchError(selector.pos, treeCopy.Apply(app, fn, tmps map ID))) + (tmps, vds, matchError(treeCopy.Apply(app, fn, tmps map ID))) } // sets temporaries, variable declarations, and the fail tree @@ -79,14 +80,14 @@ trait TransMatcher extends ast.TreeDSL { case _ => val root: Symbol = newVar(selector.pos, selector.tpe, flags) val vdef: Tree = typer.typed(ValDef(root, selector)) - val failTree: Tree = ThrowMatchError(selector.pos, ID(root)) + val failTree: Tree = matchError(ID(root)) (List(root), List(vdef), failTree) } implicit val fail: Tree = theFailTree val irep = initRep(tmps, cases, rep) - val mch = typer.typed(irep.toTree) - var dfatree = typer.typed(Block(vds, mch)) + val mch = typer typed irep.toTree + var dfatree = typer typed Block(vds, mch) // cannot use squeezedBlock because of side-effects, see t275 for ((cs, bx) <- cases.zipWithIndex) diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 6720425c79..e4c4ea9fd9 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.transform import symtab._ -import Flags._ +import Flags.{ CASE => _, _ } import scala.collection.mutable.{HashMap, ListBuffer} import matching.{TransMatcher, PatternNodes, CodeFactory, ParallelMatching} @@ -26,6 +26,7 @@ abstract class ExplicitOuter extends InfoTransform { import global._ import definitions._ + import CODE._ /** The following flags may be set by this phase: */ override def phaseNewFlags: Long = notPRIVATE | notPROTECTED | lateFINAL @@ -420,6 +421,13 @@ abstract class ExplicitOuter extends InfoTransform val tpe = new MethodType(method newSyntheticValueParams fmls, BooleanClass.tpe) method setInfo tpe + // XXX integrate + // localTyper typed (DEF(method) === { + // new ChangeOwnerTraverser(currentOwner, method) traverse guard + // new TreeSymSubstituter(vs, method.paramss.head) traverse guard + // guard + // }) + // localTyper.typed( DefDef(method, { new ChangeOwnerTraverser(currentOwner, method) traverse guard @@ -439,10 +447,10 @@ abstract class ExplicitOuter extends InfoTransform val guardDef = makeGuardDef(vs, guard) nguard += transform(guardDef) // building up list of guards - localTyper.typed(Apply(Ident(guardDef.symbol), vs map Ident)) + localTyper typed (Ident(guardDef.symbol) APPLY(vs map Ident)) } - (CODE.CASE(transform(p)) IF gdcall) ==> transform(b) + (CASE(transform(p)) IF gdcall) ==> transform(b) } def isUncheckedAnnotation(tpe: Type) = tpe hasAnnotation UncheckedClass -- cgit v1.2.3