summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-11 21:39:03 +0000
committerPaul Phillips <paulp@improving.org>2009-10-11 21:39:03 +0000
commit31c726aa43bcc97c154313e2754e5bbe5922fa41 (patch)
tree468a2e2159cc344712b06181cbe6c171b763defa /src/compiler
parent112a1dbef04bdeb8255ab4af709b2e16a79bc827 (diff)
downloadscala-31c726aa43bcc97c154313e2754e5bbe5922fa41.tar.gz
scala-31c726aa43bcc97c154313e2754e5bbe5922fa41.tar.bz2
scala-31c726aa43bcc97c154313e2754e5bbe5922fa41.zip
Added the concepts of "necessary type" and "suf...
Added the concepts of "necessary type" and "sufficient type" to Pattern to assist in creating sensible matching logic.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala4
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternBindings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala28
3 files changed, 21 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 5c27a7373c..c7c40a69ab 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -173,7 +173,7 @@ trait ParallelMatching extends ast.TreeDSL
def tail = ps.tail
def size = ps.length
- def headType = head.typeToMatch
+ def headType = head.necessaryType
def isCaseHead = head.isCaseClass
private val dummyCount = if (isCaseHead) headType.typeSymbol.caseFieldAccessors.length else 0
def dummies = emptyPatterns(dummyCount)
@@ -559,7 +559,7 @@ trait ParallelMatching extends ast.TreeDSL
def pMatchesS = matches(p, s)
def alts[T](yes: T, no: T): T = if (p =:= s) yes else no
- def isObjectTest = pattern.isObject && (p =:= pattern.typeToMatch)
+ def isObjectTest = pattern.isObject && (p =:= pattern.necessaryType)
lazy val dummy = (j, pmatch.dummies)
lazy val pass = (j, pattern)
diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
index e8dec7ff1d..563f9e64a2 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
@@ -92,7 +92,7 @@ trait PatternBindings extends ast.TreeDSL
// Like rebindToEqualsCheck, but subtly different. Not trying to be
// mysterious -- I haven't sorted it all out yet.
def rebindToObjectCheck(): Pattern = {
- val sType = typeToMatch
+ val sType = sufficientType
rebindToType(mkEqualsRef(sType), sType)
}
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 895bb7a4f3..11a2745728 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -80,7 +80,7 @@ trait Patterns extends ast.TreeDSL {
require (!isVarPattern(fn) && args.isEmpty)
val ident @ Ident(name) = fn
- override def typeToMatch = Pattern(ident).equalsCheck
+ override def sufficientType = Pattern(ident).equalsCheck
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
override def toString() = "Id(%s)".format(name)
}
@@ -88,7 +88,7 @@ trait Patterns extends ast.TreeDSL {
case class ApplySelectPattern(tree: Apply) extends ApplyPattern with SelectPattern {
val Apply(select: Select, _) = tree
- override def typeToMatch = mkSingletonFromQualifier
+ override def sufficientType = mkSingletonFromQualifier
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
override def toString() = "SelectApply(%s)".format(name)
}
@@ -101,7 +101,7 @@ trait Patterns extends ast.TreeDSL {
case class ObjectPattern(tree: Apply) extends ApplyPattern { // NamePattern?
require(!fn.isType && isModule)
- override def typeToMatch = tpe.narrow
+ override def sufficientType = tpe.narrow
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
override def toString() = "Object(%s)".format(fn)
}
@@ -129,6 +129,7 @@ trait Patterns extends ast.TreeDSL {
}
// 8.1.6
case class TuplePattern(tree: Apply) extends ApplyPattern {
+ override def necessaryType = ProductRootClass.tpe
// XXX todo
// override def irrefutableFor(tpe: Type) = false
}
@@ -139,14 +140,14 @@ trait Patterns extends ast.TreeDSL {
private val MethodType(List(arg, _*), _) = fn.tpe
private def uaTyped = Typed(tree, TypeTree(arg.tpe)) setType arg.tpe
- override def typeToMatch = arg.tpe
+ override def necessaryType = arg.tpe
// can fix #1697 here?
override def simplify(pv: PatternVar) =
if (pv.sym.tpe <:< arg.tpe) this
else this rebindTo uaTyped
- override def toString() = "Unapply(f: %s => %s)".format(typeToMatch, fn.tpe.resultType)
+ override def toString() = "Unapply(f: %s => %s)".format(necessaryType, fn.tpe.resultType)
}
// 8.1.8 (unapplySeq calls)
@@ -390,7 +391,7 @@ trait Patterns extends ast.TreeDSL {
protected def mkSingletonFromQualifier = {
def pType = qualifier match {
case _: Apply => PseudoType(tree)
- case _ => singleType(Pattern(qualifier).typeToMatch, sym)
+ case _ => singleType(Pattern(qualifier).necessaryType, sym)
}
qualifier.tpe match {
case t: ThisType => singleType(t, sym) // this.X
@@ -401,7 +402,7 @@ trait Patterns extends ast.TreeDSL {
sealed trait NamePattern extends Pattern {
def name: Name
- override def typeToMatch = tpe.narrow
+ override def sufficientType = tpe.narrow
override def simplify(pv: PatternVar) = this.rebindToEqualsCheck()
}
@@ -423,7 +424,7 @@ trait Patterns extends ast.TreeDSL {
override def dummies =
if (!this.isCaseClass) Nil
- else emptyPatterns(typeToMatch.typeSymbol.caseFieldAccessors.size)
+ else emptyPatterns(sufficientType.typeSymbol.caseFieldAccessors.size)
def isConstructorPattern = fn.isType
}
@@ -457,8 +458,15 @@ trait Patterns extends ast.TreeDSL {
// Is this a default pattern (untyped "_" or an EmptyTree inserted by the matcher)
def isDefault = false
- // what type must a scrutinee have to match this pattern?
- def typeToMatch = tpe
+ // what type must a scrutinee have to have any chance of matching this pattern?
+ def necessaryType = tpe
+
+ // what type could a scrutinee have which would automatically indicate a match?
+ // (nullness and guards will still be checked.)
+ def sufficientType = NothingClass.tpe
+ // XXX a more plausible default is:
+ //
+ // def sufficientType = tpe.narrow
// the subpatterns for this pattern (at the moment, that means constructor arguments)
def subpatterns(pm: MatchMatrix#PatternMatch): List[Pattern] = pm.dummies