summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2006-07-12 14:30:47 +0000
committerBurak Emir <emir@epfl.ch>2006-07-12 14:30:47 +0000
commitbafe0251286459b2b2259eba1a7d6dabf1c41f72 (patch)
tree5a44dc0f6fa2f0d2325c02e1a4b7e70a17b10993
parent4080a760cb70b131a6e932cb93a75a7bea4c725e (diff)
downloadscala-bafe0251286459b2b2259eba1a7d6dabf1c41f72.tar.gz
scala-bafe0251286459b2b2259eba1a7d6dabf1c41f72.tar.bz2
scala-bafe0251286459b2b2259eba1a7d6dabf1c41f72.zip
more fix, more optimization
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala23
-rw-r--r--src/compiler/scala/tools/nsc/matching/TransMatcher.scala46
-rw-r--r--test/files/run/regularpatmatnew.scala16
3 files changed, 60 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index cee49c7df5..91dcf5d69b 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -177,29 +177,6 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w
res
}
- /** returns true if apply is a "sequence apply". analyzer inserts Sequence nodes if something is a
- *
- * - last update: discussion with Martin 2005-02-18
- *
- * - if true, tree.fn must be ignored. The analyzer ensures that the selector will be a subtype
- * of fn; it thus assigns the expected type from the context (which is surely a subtype,
- * but may have different flags etc.
- *
- * - so should be
- * (( tree.args.length == 1 ) && tree.args(0).isInstanceOf[Sequence])
- * but fails
- */
- protected def isSeqApply( tree: Apply ): Boolean = {
- // Console.print("isSeqApply? "+tree.toString());
- // val res =
- tree match {
- case Apply(_, List(ArrayValue(_,_))) => (tree.tpe.symbol.flags & Flags.CASE) == 0
- case _ => false;
- }
- //Console.println(res);
- //res;
- }
-
/* currently no need for extendedSeqApply, ArrayValue in Elem(... _*) style patterns
* handled in the ArrayValue case
protected def isExtendedSeqApply( tree: Apply ): Boolean = { // NEW
diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
index 4d85f50772..73a625fe16 100644
--- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
+++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
@@ -30,6 +30,7 @@ with RightTracers {
import definitions._
import posAssigner.atPos
import typer.typed
+ import symtab.Flags
val phaseName = "transmatcher"
@@ -125,6 +126,29 @@ with RightTracers {
generatedVars
}
+ /** returns true if apply is a "sequence apply". analyzer inserts Sequence nodes if something is a
+ *
+ * - last update: discussion with Martin 2005-02-18
+ *
+ * - if true, tree.fn must be ignored. The analyzer ensures that the selector will be a subtype
+ * of fn; it thus assigns the expected type from the context (which is surely a subtype,
+ * but may have different flags etc.
+ *
+ * - so should be
+ * (( tree.args.length == 1 ) && tree.args(0).isInstanceOf[Sequence])
+ * but fails
+ */
+ protected def isSeqApply( tree: Apply ): Boolean = {
+ // Console.print("isSeqApply? "+tree.toString());
+ // val res =
+ tree match {
+ case Apply(_, List(ArrayValue(_,_))) => (tree.tpe.symbol.flags & Flags.CASE) == 0
+ case _ => false;
+ }
+ //Console.println(res);
+ //res;
+ }
+
/** a casedef with sequence subpatterns like
*
* case ..x @ ().. => body
@@ -219,7 +243,8 @@ with RightTracers {
//case ArrayValue( tt, List(b @ Bind(id, Star(wc @ Ident(nme.WILDCARD))))) =>
- case Apply(fn, List(pat2@ ArrayValue( tt, List(b @ Bind(id, Star(wc @ Ident(nme.WILDCARD))))))) =>
+ // a pattern of the form List(foo@_*)
+ case app @ Apply(fn, List(pat2@ ArrayValue( tt, List(b @ Bind(id, Star(wc @ Ident(nme.WILDCARD))))))) if isSeqApply(app) =>
//Console.println("OPTIMIZING")
//Console.println(pat)
//Console.println(pat.tpe)
@@ -237,6 +262,25 @@ with RightTracers {
//Console.println(res)
res
+ // a pattern of the form MyCaseConstructor(foo@_*)
+ case app @ Apply(fn, List(pat2@ ArrayValue( tt, List(b @ Bind(id, Star(wc @ Ident(nme.WILDCARD))))))) =>
+ //Console.println("OPTIMIZING")
+ //Console.println(pat)
+ //Console.println(pat.tpe)
+ //Console.println(tt.tpe)
+ //Console.println("b.tpe "+b.tpe+" widened"+b.tpe.widen)
+ //Console.println("b.symbol.tpe "+b.symbol.tpe+" widened"+b.symbol.tpe.widen)
+ //Console.println("pat2.tpe "+pat2.tpe+" widened"+pat2.tpe.widen)
+ val tpe1:Type = pat2.tpe.widen.baseType( definitions.SeqClass ).typeArgs(0)
+
+ val tpe = appliedType(definitions.SeqClass.typeConstructor, List(tpe1))
+ b.symbol.setInfo(tpe)
+ b.setType(tpe)
+ val res = copy.Apply(pat, fn, List(copy.Bind(b, id, wc)))
+ //Console.println("====>")
+ //Console.println(res)
+ res
+
case av @ ArrayValue(s, trees) =>
if (isRightIgnoring(av)) pat
else copy.ArrayValue(pat, s, (trees map { isRegular1 }))
diff --git a/test/files/run/regularpatmatnew.scala b/test/files/run/regularpatmatnew.scala
index 444b36e32f..617293028c 100644
--- a/test/files/run/regularpatmatnew.scala
+++ b/test/files/run/regularpatmatnew.scala
@@ -8,7 +8,8 @@ object Test {
new Test01,
new Test02,
new Test03,
- new Test04
+ new Test04,
+ new Test05
).run(tr)
@@ -95,5 +96,18 @@ object Test {
}
}
+ class Test05 extends TestCase("cinque (sealed case class with ignoring seq patterns)") {
+ sealed abstract class Con;
+
+ case class Foo() extends Con
+ case class Bar(xs:Con*) extends Con
+
+ override def runTest() = {
+ val res = (Bar(Foo()):Con) match {
+ case Bar(xs@_*) => xs // this should be optimized away to a pattern Bar(xs)
+ }
+ assertEquals("res instance"+res.isInstanceOf[Seq[Con]]+" res(0)="+res(0), true, res.isInstanceOf[Seq[Foo]] && res(0) == Foo() )
+ }
+ }
}