summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala82
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternBindings.scala6
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternNodes.scala5
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala36
4 files changed, 48 insertions, 81 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index f39a2d0f08..a904b9026d 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -87,60 +87,7 @@ trait ParallelMatching extends ast.TreeDSL
/** the injection here handles alternatives and unapply type tests */
final def make(tvars: List[Symbol], row1: List[Row]): Rep = {
- def classifyPat(opat: Pattern, j: Int): Pattern = {
- def testVar = tvars(j)
-
- // @pre for doUnapplySeq: is not right-ignoring (no star pattern) ; no exhaustivity check
- def doUnapplySeq(tptArg: Tree, xs: List[Tree]) = {
- testVar setFlag Flags.TRANS_FLAG
-
- opat rebindTo normalizedListPattern(xs, tptArg.tpe)
- }
- def doValMatch(x: Tree, fn: Tree) = {
- val p = Pattern(x)
-
- def examinePrefix(path: Tree) = (path, path.tpe) match {
- case (_, t: ThisType) => singleType(t, x.symbol) // cases 2/3 are e.g. `case Some(p._2)' in s.c.jcl.Map
- case (_: Apply, _) => PseudoType(x) // outer-matching: test/files/pos/t154.scala
- case _ => singleType(Pattern(path).mkSingleton, x.symbol) // old
- }
- val singletonType =
- if (p.isModule) p.mkSingleton else fn match {
- case Select(path, _) => examinePrefix(path)
- case x: Ident => Pattern(fn).equalsCheck
- }
- val typeToTest = mkEqualsRef(singletonType)
-
- val t = Typed(WILD(typeToTest), TypeTree(singletonType)) setType typeToTest
- opat rebindTo t
- }
-
- def doReturnOriginal(t: Tree) = cond(t) {
- case EmptyTree | WILD() | _: Literal | _: Typed | _: ArrayValue => true
- }
-
- // NOTE - this seemingly pointless representation has a point. Until extractors
- // can be trusted, I only feel safe using them by using one to a match, because it is
- // in the transitions they are broken. This will return to a more traditional
- // pattern match before the final curtain falls.
- val f = List[PartialFunction[Tree, Pattern]](
- { case _: Alternative => opat } ,
- { case _: Typed => opat simplify testVar } ,
- { case x if doReturnOriginal(x) => opat } ,
- // This busts things for now
- // { case _: Ident => opat.simplify() } ,
- { case _: Ident | _: Select => opat.rebindToEqualsCheck() } ,
- { case _: This => opat } ,
- { case UnapplySeq(tptArg, xs) => doUnapplySeq(tptArg, xs) } ,
- { case UnApply(Apply(fn, _), _) => opat simplify testVar } ,
- { case x @ Apply_Function(fn) => doValMatch(x, fn) } ,
- { case Apply_Value(_, _) => opat simplify testVar } ,
- { case Apply_CaseClass(_, _) => opat.simplify() } ,
- { case x => abort("Unexpected pattern: " + x.getClass + " => " + x) }
- ) reduceLeft (_ orElse _)
-
- f(opat.tree)
- }
+ def classifyPat(opat: Pattern, j: Int): Pattern = opat simplify tvars(j)
val rows = row1 flatMap (_ expandAlternatives classifyPat)
if (rows.length != row1.length) make(tvars, rows) // recursive call if any change
@@ -202,8 +149,6 @@ trait ParallelMatching extends ast.TreeDSL
def dummyPatterns = dummies map (x => Pattern(x))
def apply(i: Int): Pattern = ps(i)
- // XXX temp
- def zip() = trees.zipWithIndex
def pzip() = ps.zipWithIndex
def zip[T](others: List[T]) = trees zip others
def pzip[T](others: List[T]) = ps zip others
@@ -218,9 +163,9 @@ trait ParallelMatching extends ast.TreeDSL
val (lits, others) = trees span isSwitchableConst
others match {
- case Nil => Some(lits, None)
+ case Nil => Some((lits, None))
// TODO: This needs to also allow the case that the last is a compatible type pattern.
- case List(x) if isSwitchableDefault(x) => Some(lits, Some(x))
+ case List(x) if isSwitchableDefault(x) => Some((lits, Some(x)))
case _ => None
}
}
@@ -540,7 +485,7 @@ trait ParallelMatching extends ast.TreeDSL
def getTransition(): Branch[TransitionContext] = {
assert(scrut.tpe <:< head.tpe, "fatal: %s is not <:< %s".format(scrut, head.tpe))
- val av @ ArrayValue(_, elems) = head.boundTree
+ val av @ ArrayValue(_, elems) = head.tree
val ys = if (isRightIgnoring(av)) elems.init else elems
val vs = ys map (y => newVar(unbind(y).pos, scrut.elemType))
def scrutCopy = scrut.id.duplicate
@@ -658,7 +603,10 @@ trait ParallelMatching extends ast.TreeDSL
// remaining: remaining, rows 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 @ Stripped(spat), j) <- pats.zip) yield {
+ for ((pattern, j) <- pats.pzip()) yield {
+ val spat: Tree = pattern.tree
+ val pat: Tree = pattern.boundTree
+
def eqHead(tpe: Type) = pats.headType =:= tpe
def alts(yes: Tree, no: Tree) = if (eqHead(pat.tpe)) yes else no
@@ -711,6 +659,8 @@ trait ParallelMatching extends ast.TreeDSL
/** returns casted symbol, success matrix and optionally fail matrix for type test on the top of this column */
final def getTransition(): Branch[Scrutinee] = {
val casted = scrut castedTo pats.headType
+ // val neededCast = (scrut ne casted)
+
val isAnyMoreSpecific = moreSpecific exists (x => !x.isEmpty)
def mkZipped = moreSpecific zip subsumed map { case (mspat, (j, pats)) => (j, mspat :: pats) }
@@ -1000,18 +950,18 @@ trait ParallelMatching extends ast.TreeDSL
final def expand(roots: List[Symbol], cases: List[Tree]): ExpandedMatrix = {
val (rows, finals) = List.unzip(
for ((CaseDef(pat, guard, body), index) <- cases.zipWithIndex) yield {
- def mkRow(ps: List[Tree]) = Row(toPats(ps), NoBinding, Guard(guard), index)
+ def mkRow(ps: List[Pattern]) = Row(ps, NoBinding, Guard(guard), index)
- def rowForPat: Option[Row] = condOpt(pat) {
- case _ if roots.length <= 1 => mkRow(List(pat))
- case Apply(fn, args) => mkRow(args)
- case WILD() => mkRow(getDummies(roots.length))
+ def rowForPat = pat match {
+ case _ if roots.length <= 1 => mkRow(List(Pattern(pat)))
+ case Apply(fn, args) => mkRow(toPats(args))
+ case WILD() => mkRow(emptyPatterns(roots.length))
}
(rowForPat, FinalState(NoBinding, body, definedVars(pat)))
}
)
- new ExpandedMatrix(rows flatMap (x => x), finals)
+ new ExpandedMatrix(rows, finals)
}
/** returns the condition in "if (cond) k1 else k2"
diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
index eeb8938b6a..575050821a 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
@@ -21,6 +21,12 @@ trait PatternBindings extends ast.TreeDSL
def mkEqualsRef(tpe: Type) = typeRef(NoPrefix, EqualsPatternClass, List(tpe))
def decodedEqualsType(tpe: Type) = condOpt(tpe) { case TypeRef(_, EqualsPatternClass, List(arg)) => arg } getOrElse (tpe)
+ // used as argument to `EqualsPatternClass'
+ case class PseudoType(o: Tree) extends SimpleTypeProxy {
+ override def underlying: Type = o.tpe
+ override def safeToString: String = "PseudoType("+o+")"
+ }
+
// If the given pattern contains alternatives, return it as a list of patterns.
// Makes typed copies of any bindings found so all alternatives point to final state.
def extractBindings(p: Tree, prevBindings: Tree => Tree = identity[Tree] _): List[Tree] = {
diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
index 19baaab00a..dd9022cd2d 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
@@ -114,11 +114,6 @@ trait PatternNodes extends ast.TreeDSL
}
}
- // used as argument to `EqualsPatternClass'
- case class PseudoType(o: Tree) extends SimpleTypeProxy {
- override def underlying: Type = o.tpe
- override def safeToString: String = "PseudoType("+o+")"
- }
}
/** For folding a list into a well-typed x :: y :: etc :: tree. */
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 2bc76b57f1..6c72caed0c 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -48,6 +48,7 @@ trait Patterns extends ast.TreeDSL {
// 8.1.1
case class VariablePattern(tree: Ident) extends Pattern {
override def irrefutableFor(tpe: Type) = true
+ override def simplify(testVar: Symbol) = this.rebindToEqualsCheck()
}
// 8.1.1 (b)
@@ -72,17 +73,14 @@ trait Patterns extends ast.TreeDSL {
// 8.1.4
case class StableIdPattern(tree: Ident) extends Pattern {
- override def simplify(testVar: Symbol) = rebindToEqualsCheck()
+ override def simplify(testVar: Symbol) = this.rebindToEqualsCheck()
}
// 8.1.4 (b)
case class SelectPattern(tree: Select) extends Pattern {
- // override def simplify(testVar: Symbol) =
- // this rebindToEmpty mkEqualsRef(singleType(pre, sym))
+ override def simplify(testVar: Symbol) = this.rebindToEqualsCheck()
}
- // 8.1.4 (b)
-
// 8.1.5
case class ConstructorPattern(tree: Apply) extends ApplyPattern {
require(fn.isType)
@@ -98,8 +96,22 @@ trait Patterns extends ast.TreeDSL {
case class ApplyValuePattern(tree: Apply) extends ApplyPattern {
require(!fn.isType)
- override def simplify(testVar: Symbol) =
- this rebindToEmpty mkEqualsRef(singleType(prefix, sym))
+ override def simplify(testVar: Symbol) = {
+ def examinePrefix(path: Tree) = (path, path.tpe) match {
+ case (_, t: ThisType) => singleType(t, sym)
+ case (_: Apply, _) => PseudoType(tree)
+ case _ => singleType(Pattern(path).mkSingleton, sym)
+ }
+ val singletonType =
+ if (isModule) mkSingleton else fn match {
+ case Select(path, _) => examinePrefix(path)
+ case x: Ident => Pattern(x).equalsCheck
+ }
+
+ val typeToTest = mkEqualsRef(singletonType)
+ val tt = Typed(WILD(typeToTest), TypeTree(singletonType)) setType typeToTest
+ this rebindTo tt
+ }
}
// 8.1.6
@@ -114,6 +126,7 @@ trait Patterns extends ast.TreeDSL {
private val MethodType(List(arg, _*), _) = fn.tpe
private def uaTyped = Typed(tree, TypeTree(arg.tpe)) setType arg.tpe
+ // can fix #1697 here?
override def simplify(testVar: Symbol) =
if (testVar.tpe <:< arg.tpe) this
else this rebindTo uaTyped
@@ -154,10 +167,13 @@ trait Patterns extends ast.TreeDSL {
// XXX - temporary pattern until we have integrated every tree type.
case class MiscPattern(tree: Tree) extends Pattern {
- // println("Resorted to MiscPattern: %s/%s".format(tree, tree.getClass))
+ log("Resorted to MiscPattern: %s/%s".format(tree, tree.getClass))
+ override def simplify(testVar: Symbol) = tree match {
+ case x: Ident => this.rebindToEqualsCheck()
+ case _ => super.simplify(testVar)
+ }
}
-
object Pattern {
def isDefaultPattern(t: Tree) = cond(unbind(t)) { case EmptyTree | WILD() => true }
def isStar(t: Tree) = cond(unbind(t)) { case Star(q) => isDefaultPattern(q) }
@@ -238,7 +254,7 @@ trait Patterns extends ast.TreeDSL {
// The logic formerly in classifyPat, returns either a simplification
// of this pattern or identity.
def simplify(testVar: Symbol): Pattern = this
- def simplify(): Pattern = simplify(NoSymbol)
+ def simplify(): Pattern = this simplify NoSymbol
def subpatterns(pats: MatchMatrix#Patterns): List[Pattern] = Nil