<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -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 &amp;&amp; (p =:= pattern.typeToMatch)
+          def isObjectTest              = pattern.isObject &amp;&amp; (p =:= pattern.necessaryType)
 
           lazy val dummy          = (j, pmatch.dummies)
           lazy val pass           = (j, pattern)</diff>
      <filename>src/compiler/scala/tools/nsc/matching/ParallelMatching.scala</filename>
    </modified>
    <modified>
      <diff>@@ -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>
      <filename>src/compiler/scala/tools/nsc/matching/PatternBindings.scala</filename>
    </modified>
    <modified>
      <diff>@@ -80,7 +80,7 @@ trait Patterns extends ast.TreeDSL {
     require (!isVarPattern(fn) &amp;&amp; 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() = &quot;Id(%s)&quot;.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() = &quot;SelectApply(%s)&quot;.format(name)
   }
@@ -101,7 +101,7 @@ trait Patterns extends ast.TreeDSL {
   case class ObjectPattern(tree: Apply) extends ApplyPattern {  // NamePattern?
     require(!fn.isType &amp;&amp; isModule)
     
-    override def typeToMatch = tpe.narrow
+    override def sufficientType = tpe.narrow
     override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
     override def toString() = &quot;Object(%s)&quot;.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 &lt;:&lt; arg.tpe) this
       else this rebindTo uaTyped
       
-    override def toString() = &quot;Unapply(f: %s =&gt; %s)&quot;.format(typeToMatch, fn.tpe.resultType)
+    override def toString() = &quot;Unapply(f: %s =&gt; %s)&quot;.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 =&gt; PseudoType(tree)
-        case _        =&gt; singleType(Pattern(qualifier).typeToMatch, sym)
+        case _        =&gt; singleType(Pattern(qualifier).necessaryType, sym)
       }
       qualifier.tpe match {
         case t: ThisType  =&gt; 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 &quot;_&quot; 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</diff>
      <filename>src/compiler/scala/tools/nsc/matching/Patterns.scala</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>7ea628fc5b9cf45e16bd323163fc20922e7bd8c2</id>
    </parent>
  </parents>
  <author>
    <name>extempore</name>
    <email>extempore@5e8d7ff9-d8ef-0310-90f0-a4852d11357a</email>
  </author>
  <url>http://github.com/paulp/scala/commit/8151c110e1d05f1403da73e62804f083c3892eba</url>
  <id>8151c110e1d05f1403da73e62804f083c3892eba</id>
  <committed-date>2009-10-11T14:39:03-07:00</committed-date>
  <authored-date>2009-10-11T14:39:03-07:00</authored-date>
  <message>Added the concepts of &quot;necessary type&quot; and &quot;sufficient type&quot;
to Pattern to assist in creating sensible matching logic.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@19049 5e8d7ff9-d8ef-0310-90f0-a4852d11357a</message>
  <tree>aece3b7d3082d0324fb1f6e70d8adbe114f612cd</tree>
  <committer>
    <name>extempore</name>
    <email>extempore@5e8d7ff9-d8ef-0310-90f0-a4852d11357a</email>
  </committer>
</commit>
