<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -158,6 +158,7 @@ trait Matrix extends MatrixAdditions {
 
       override def toString() = &quot;%s: %s = %s&quot;.format(lhs, lhs.info, rhs)
     }
+    // val NoPatternVar = PatternVar(NoSymbol, EmptyTree, false)
     
     /** Sets the rhs to EmptyTree, which makes the valDef ignored in Scrutinee.
      */</diff>
      <filename>src/compiler/scala/tools/nsc/matching/Matrix.scala</filename>
    </modified>
    <modified>
      <diff>@@ -53,12 +53,15 @@ trait ParallelMatching extends ast.TreeDSL
       -shortCuts.length
     }
 
+    // XXX transitional.
+    final def requestBody(bx: Int, subst: Bindings): Tree =
+      requestBody(bx, PatternVarGroup.fromBindings(subst.get(), targets(bx).freeVars))
+     
     /** first time bx is requested, a LabelDef is returned. next time, a jump.
      *  the function takes care of binding
      */
-    final def requestBody(bx: Int, subst: Bindings): Tree = {
-      val target @ FinalState(tbx, body, freeVars) = targets(bx)
-      val pvgroup = PatternVarGroup.fromBindings(subst.get(), freeVars)
+    final def requestBody(bx: Int, pvgroup: PatternVarGroup): Tree = {
+      val target = targets(bx)
       
       // shortcut
       if (bx &lt; 0) Apply(ID(shortCuts(-bx-1)), Nil)      
@@ -70,7 +73,7 @@ trait ParallelMatching extends ast.TreeDSL
 
     /** the injection here handles alternatives and unapply type tests */
     final def make(tvars: PatternVarGroup, row1: List[Row]): Rep = {
-      def classifyPat(opat: Pattern, j: Int): Pattern = opat simplify tvars(j).sym
+      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
@@ -114,10 +117,13 @@ trait ParallelMatching extends ast.TreeDSL
       // sequences
       def seqType         = tpe.widen baseType SeqClass
       def elemType        = tpe typeArgs 0
-      def elemAt(i: Int)  = (id DOT (tpe member nme.apply))(LIT(i))
-
-      def createElemVar(i: Int)   = createVar(elemType, _ =&gt; elemAt(i))
-      def createSeqVar(drop: Int) = createVar(seqType, _ =&gt; id DROP drop)
+      
+      private def elemAt(i: Int)  = (id DOT (tpe member nme.apply))(LIT(i))
+      private def createElemVar(i: Int)   = createVar(elemType, _ =&gt; elemAt(i))
+      private def createSeqVar(drop: Int) = createVar(seqType, _ =&gt; id DROP drop)
+          
+      def createSequenceVars(count: Int): List[PatternVar] =
+        (0 to count).toList map (i =&gt; if (i &lt; count) createElemVar(i) else createSeqVar(i))
 
       // for propagating &quot;unchecked&quot; to synthetic vars
       def isChecked = !(sym hasFlag TRANS_FLAG)
@@ -171,6 +177,7 @@ trait ParallelMatching extends ast.TreeDSL
       def isCaseHead = head.isCaseClass
       private val dummyCount = if (isCaseHead) headType.typeSymbol.caseFieldAccessors.length else 0
       def dummies = emptyPatterns(dummyCount)
+      // def dummies = head.dummies
 
       def apply(i: Int): Pattern = ps(i)
       def pzip() = ps.zipWithIndex
@@ -362,7 +369,8 @@ trait ParallelMatching extends ast.TreeDSL
         private def sameFunction(fn1: Tree) = fxn.symbol == fn1.symbol &amp;&amp; (fxn equalsStructure fn1)
 
         def unapply(p: Pattern) = condOpt(p) {
-          case Pattern(UnApply(Apply(fn1, _), args), _) if sameFunction(fn1)  =&gt; args
+          case Pattern(UnApply(Apply(fn1, _), args), _) if sameFunction(fn1)  =&gt;
+            tracing(&quot;sameUnapply&quot;, args)
         }
       }      
       object SameUnapply {
@@ -373,13 +381,6 @@ trait ParallelMatching extends ast.TreeDSL
       }
       def isSameUnapply(p: Pattern) = SameUnapply.unapply(p).isDefined
       
-      // Second argument is number of dummies to prepend in the default case
-      def mkNewRows(sameFilter: (List[Tree]) =&gt; List[Tree], dum: Int) =
-        for ((pat, r) &lt;- zipped) yield pat match {
-          case sameUnapplyCall(args)  =&gt; r.insert2(toPats(sameFilter(args)) ::: List(NoPattern), pat.boundVariables, scrut.sym)
-          case _                      =&gt; r insert (emptyPatterns(dum) ::: List(pat))
-        }
-      
       lazy val cond: Tree =
         if (unapplyResult.tpe.isBoolean) ID(unapplyResult.valsym)
         else unapplyResult.valsym IS_DEFINED
@@ -402,12 +403,21 @@ trait ParallelMatching extends ast.TreeDSL
         lazy val tuplePVs =
           for ((tpe, i) &lt;- tpes.zipWithIndex) yield
             scrut.createVar(tpe, _ =&gt; fn(ID(tuple), productProj(tuple, i + 1)))
+            
+        // the filter prevents infinite unapply recursion
+        def mkNewRows(sameFilter: (List[Tree]) =&gt; List[Tree]) = {
+          val dum = if (args.length &lt;= 1) args.length else tpes.size
+          for ((pat, r) &lt;- zipped) yield pat match {
+            case sameUnapplyCall(xs)  =&gt; r.insert2(toPats(sameFilter(xs)) ::: List(NoPattern), pat.boundVariables, scrut.sym)
+            case _                    =&gt; r insert (emptyPatterns(dum) ::: List(pat))
+          }
+        }
 
         // 0 is Boolean, 1 is Option[T], 2+ is Option[(T1,T2,...)]
         args.length match {
-          case 0  =&gt; (Nil, Nil, mkNewRows((xs) =&gt; Nil, 0))
-          case 1  =&gt; (List(pv), List(pv), mkNewRows(xs =&gt; List(xs.head), 1))
-          case _  =&gt; (pv :: tuplePVs, tuplePVs, mkNewRows(identity, tpes.size))
+          case 0  =&gt; (Nil, Nil, mkNewRows((xs) =&gt; Nil))
+          case 1  =&gt; (List(pv), List(pv), mkNewRows(xs =&gt; List(xs.head)))
+          case _  =&gt; (pv :: tuplePVs, tuplePVs, mkNewRows(identity))
         }
       }
 
@@ -437,7 +447,8 @@ trait ParallelMatching extends ast.TreeDSL
       }
       
       def getSubPatterns(x: Pattern): Option[List[Pattern]] = {
-        def defaults = Some(emptyPatterns(pivot.elemPatterns.length + 1))
+        // def defaults = Some(emptyPatterns(pivot.elemPatterns.length + 1))
+        def defaults = Some(pivot.dummies)
         val av @ ArrayValue(_, xs) = x.tree match {
           case x: ArrayValue      =&gt; x
           case EmptyTree | WILD() =&gt; return defaults
@@ -467,8 +478,7 @@ trait ParallelMatching extends ast.TreeDSL
         assert(scrut.tpe &lt;:&lt; head.tpe, &quot;fatal: %s is not &lt;:&lt; %s&quot;.format(scrut, head.tpe))
         
         // one pattern var per sequence element up to elemCount, and one more for the rest of the sequence
-        val elemCount = pivot.nonStarPatterns.size
-        val pvs = ((0 until elemCount).toList map (scrut createElemVar _)) ::: List(scrut createSeqVar elemCount)
+        val pvs = scrut createSequenceVars pivot.nonStarPatterns.size
 
         val (nrows, frows): (List[Option[Row]], List[Option[Row]]) = List.unzip(
           for ((c, rows) &lt;- pmatch pzip rest.rows) yield getSubPatterns(c) match {
@@ -663,11 +673,12 @@ trait ParallelMatching extends ast.TreeDSL
 
       // returns this rows with alternatives expanded
       def expandAlternatives(classifyPat: (Pattern, Int) =&gt; Pattern): List[Row] = {
+        def isNotAlternative(p: Pattern) = !cond(p.tree) { case _: Alternative =&gt; true }
+        
         // classify all the top level patterns - alternatives come back unaltered
         val newPats: List[Pattern] = pats.zipWithIndex map tupled(classifyPat)        
         // see if any alternatives were in there
-        val (ps, others) = newPats span (x =&gt; !x.isAlternative)
-        
+        val (ps, others) = newPats span isNotAlternative
         // make a new row for each alternative, with it spliced into the original position
         if (others.isEmpty) List(copy(pats = ps))
         else extractBindings(others.head) map (x =&gt; replaceAt(ps.size, x))
@@ -684,8 +695,14 @@ trait ParallelMatching extends ast.TreeDSL
     class ExpandedMatrix(val rows: List[Row], val targets: List[FinalState]) {
       require(rows.size == targets.size)
       
-      override def toString() =
-        &quot;ExpandedMatrix(%d)&quot;.format(rows.size) + pp(rows zip targets, true)
+      override def toString() = {
+        def rprint(r: Row) = &quot;Row %d: %d pats, %d bound&quot;.format(r.bx, r.pats.size, r.subst.get().size)
+        def tprint(t: FinalState) = &quot;%s (free = %s)&quot;.format(t.body, pp(t.freeVars))
+        val xs = rows zip targets map { case (r,t) =&gt; rprint(r) -&gt; tprint(t) }
+        val ppstr = pp(xs, newlines = true)
+                    
+        &quot;ExpandedMatrix(%d rows)&quot;.format(rows.size) + ppstr
+      }
     }
     
     abstract class State {</diff>
      <filename>src/compiler/scala/tools/nsc/matching/ParallelMatching.scala</filename>
    </modified>
    <modified>
      <diff>@@ -23,7 +23,8 @@ trait Patterns extends ast.TreeDSL {
   import Debug._
   import treeInfo.{ unbind, isVarPattern }
   
-  type PatternMatch = MatchMatrix#PatternMatch
+  type PatternMatch       = MatchMatrix#PatternMatch
+  private type PatternVar = MatrixContext#PatternVar
   
   // Fresh patterns
   def emptyPatterns(i: Int): List[Pattern] = List.fill(i)(NoPattern)
@@ -58,8 +59,8 @@ trait Patterns extends ast.TreeDSL {
     override def subpatternsForVars: List[Pattern] = List(Pattern(expr))
     
     override def irrefutableFor(tpe: Type) = tpe &lt;:&lt; tree.tpe
-    override def simplify(testVar: Symbol) = Pattern(expr) match {
-      case ExtractorPattern(ua) if testVar.tpe &lt;:&lt; tpt.tpe  =&gt; this rebindTo expr
+    override def simplify(pv: PatternVar) = Pattern(expr) match {
+      case ExtractorPattern(ua) if pv.sym.tpe &lt;:&lt; tpt.tpe  =&gt; this rebindTo expr
       case _                                                =&gt; this
     }
     override def toString() = &quot;%s: %s&quot;.format(Pattern(expr), tpt)
@@ -80,7 +81,7 @@ trait Patterns extends ast.TreeDSL {
     val ident @ Ident(name) = fn
 
     override def typeToMatch = Pattern(ident).equalsCheck
-    override def simplify(testVar: Symbol) = this.rebindToObjectCheck()
+    override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
     override def toString() = &quot;Id(%s)&quot;.format(name)
   }
   // 8.1.4 (b)
@@ -88,7 +89,7 @@ trait Patterns extends ast.TreeDSL {
     val Apply(select: Select, _) = tree
     
     override def typeToMatch = mkSingletonFromQualifier
-    override def simplify(testVar: Symbol) = this.rebindToObjectCheck()
+    override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
     override def toString() = &quot;SelectApply(%s)&quot;.format(name)
   }
   // 8.1.4 (c)
@@ -101,7 +102,7 @@ trait Patterns extends ast.TreeDSL {
     require(!fn.isType &amp;&amp; isModule)
     
     override def typeToMatch = tpe.narrow
-    override def simplify(testVar: Symbol) = this.rebindToObjectCheck()
+    override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
     override def toString() = &quot;Object(%s)&quot;.format(fn)
   }
   // 8.1.4 (e)
@@ -114,10 +115,10 @@ trait Patterns extends ast.TreeDSL {
     require(fn.isType &amp;&amp; this.isCaseClass)
 
     override def subpatterns(pm: MatchMatrix#PatternMatch) = 
-      if (pm.isCaseHead) args map Pattern.apply
+      if (pm.head.isCaseClass) args map Pattern.apply
       else super.subpatterns(pm)
     
-    override def simplify(testVar: Symbol) =
+    override def simplify(pv: PatternVar) =
       if (args.isEmpty) this rebindToEmpty tree.tpe
       else this
     
@@ -141,8 +142,8 @@ trait Patterns extends ast.TreeDSL {
     override def typeToMatch = arg.tpe
     
     // can fix #1697 here?
-    override def simplify(testVar: Symbol) =
-      if (testVar.tpe &lt;:&lt; arg.tpe) this
+    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)
@@ -175,8 +176,8 @@ trait Patterns extends ast.TreeDSL {
     }
 
     // @pre: is not right-ignoring (no star pattern) ; no exhaustivity check
-    override def simplify(testVar: Symbol) = {
-      testVar setFlag Flags.TRANS_FLAG
+    override def simplify(pv: PatternVar) = {
+      pv.sym setFlag Flags.TRANS_FLAG
       this rebindTo elems.foldRight(gen.mkNil)(listFolder)
     }
     override def toString() = &quot;UnapplySeq(%s)&quot;.format(elems)
@@ -194,6 +195,8 @@ trait Patterns extends ast.TreeDSL {
     def hasStar = elems.nonEmpty &amp;&amp; (cond(lastPattern) { case _: StarPattern =&gt; true })
     def nonStarLength = nonStarPatterns.length
     def isAllDefaults = nonStarPatterns forall (_.isDefault)
+    
+    override def dummies = emptyPatterns(elemPatterns.length + 1)    
 
     def rebindStar(seqType: Type): List[Pattern] = {
       require(hasStar)
@@ -399,13 +402,9 @@ trait Patterns extends ast.TreeDSL {
   sealed trait NamePattern extends Pattern {
     def name: Name
     override def typeToMatch = tpe.narrow
-    override def simplify(testVar: Symbol) = this.rebindToEqualsCheck()
+    override def simplify(pv: PatternVar) = this.rebindToEqualsCheck()
   }
   
-  // trait SimplePattern extends Pattern {
-  //   def simplify(testVar: Symbol): Pattern = this
-  // }  
-  
   sealed trait UnapplyPattern extends Pattern {
     lazy val UnApply(unfn, args) = tree
     override def subpatternsForVars: List[Pattern] = toPats(args)
@@ -421,6 +420,10 @@ trait Patterns extends ast.TreeDSL {
   sealed trait ApplyPattern extends Pattern {
     protected lazy val Apply(fn, args) = tree
     override def subpatternsForVars: List[Pattern] = toPats(args)
+    
+    override def dummies =
+      if (!this.isCaseClass) Nil
+      else emptyPatterns(typeToMatch.typeSymbol.caseFieldAccessors.size)
 
     def isConstructorPattern = fn.isType    
   }
@@ -429,8 +432,11 @@ trait Patterns extends ast.TreeDSL {
     val tree: Tree
 
     // returns either a simplification of this pattern or identity.
-    def simplify(testVar: Symbol): Pattern = this
-    def simplify(): Pattern = this simplify NoSymbol
+    def simplify(pv: PatternVar): Pattern = this
+    def simplify(): Pattern = this simplify null
+    
+    // the right number of dummies for this pattern
+    def dummies: List[Pattern] = Nil
     
     // given this scrutinee, what if any condition must be satisfied before
     // we even try to match?
@@ -477,8 +483,6 @@ trait Patterns extends ast.TreeDSL {
         if (sym.isValue) singleType(NoPrefix, sym)
         else tpe.narrow
       )
-
-    final def isAlternative       = cond(tree) { case Alternative(_) =&gt; true }
     
     /** Standard methods **/
     def copy(tree: Tree = this.tree): Pattern = </diff>
      <filename>src/compiler/scala/tools/nsc/matching/Patterns.scala</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>69fcfedcf02154b1ea630dd77b0557daeac7b38f</id>
    </parent>
  </parents>
  <author>
    <name>extempore</name>
    <email>extempore@5e8d7ff9-d8ef-0310-90f0-a4852d11357a</email>
  </author>
  <url>http://github.com/paulp/scala/commit/7ea628fc5b9cf45e16bd323163fc20922e7bd8c2</url>
  <id>7ea628fc5b9cf45e16bd323163fc20922e7bd8c2</id>
  <committed-date>2009-10-11T13:17:32-07:00</committed-date>
  <authored-date>2009-10-11T13:17:32-07:00</authored-date>
  <message>Further iteration related to patterns and bindings.

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