summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-29 20:13:33 +0000
committerPaul Phillips <paulp@improving.org>2009-06-29 20:13:33 +0000
commit96f6c893f1ad84ef81e975820af566a926a246c3 (patch)
tree38f3c0fc56c98bd0ee1f924c1427cddd8548272d /src
parentfe1d043034c3194b8b72e852686a7334f0dab879 (diff)
downloadscala-96f6c893f1ad84ef81e975820af566a926a246c3.tar.gz
scala-96f6c893f1ad84ef81e975820af566a926a246c3.tar.bz2
scala-96f6c893f1ad84ef81e975820af566a926a246c3.zip
Working on the pattern matcher.
in the parts I mostly understand to terms more evocative than e.g. "strip2".
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala6
-rw-r--r--src/compiler/scala/tools/nsc/matching/CodeFactory.scala28
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala85
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternNodes.scala45
-rw-r--r--src/compiler/scala/tools/nsc/matching/TransMatcher.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala14
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 <equals>
+ case Typed(p @ Stripped(_: UnApply), _) if xIsaY => (p, dummy, None) // <:< is never <equals>
case q @ Typed(pp, _) if xIsaY => (alts(pp, q), dummy, None) // never =:= for <equals>
case z: UnApply => (None, None, pass)
case _ if erased.xIsaY || xIsaY && !isDef => (alts(EmptyTree, pat), subs, None) // never =:= for <equals>
@@ -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