diff options
author | Paul Phillips <paulp@improving.org> | 2009-10-11 21:39:03 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-10-11 21:39:03 +0000 |
commit | 31c726aa43bcc97c154313e2754e5bbe5922fa41 (patch) | |
tree | 468a2e2159cc344712b06181cbe6c171b763defa /src | |
parent | 112a1dbef04bdeb8255ab4af709b2e16a79bc827 (diff) | |
download | scala-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')
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 |