summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/matching/CodeFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala52
-rw-r--r--test/files/run/regularpatmatnew.check0
-rw-r--r--test/files/run/regularpatmatnew.scala74
4 files changed, 104 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
index d879b9be47..943df9571e 100644
--- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
+++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala
@@ -186,7 +186,7 @@ trait CodeFactory requires TransMatcher {
*/
def Equals(left: Tree , right: Tree ): Tree = Apply(Select(left, nme.EQEQ), List(right));
- def GreaterThan(left: Tree , right: Tree ): Tree = Apply(Select(left, nme.GT), List(right));
+ def GreaterThanOrEquals(left: Tree , right: Tree ): Tree = Apply(Select(left, nme.GE), List(right));
def ThrowMatchError(pos: Int, obj: Tree ) =
atPos(pos) {
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 1ff21e60eb..68c591b2e7 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -1037,33 +1037,39 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w
case RightIgnoringSequencePat(casted, castedRest, minlen) =>
Or(
- And(
- And(gen.mkIsInstanceOf(selector.duplicate, node.getTpe()),
- GreaterThan(
- typed(
- Apply(
- Select(
- gen.mkAsInstanceOf(selector.duplicate,
- node.getTpe(),
- true),
- node.getTpe().member(nme.length) /*defs.Seq_length*/),
- List())
- ),
- typed(
- Literal(Constant(minlen))
- ))),
+ And({
+ var cond:Tree = gen.mkIsInstanceOf(selector.duplicate, node.getTpe()); // test for sequence
+
+ if(minlen > 0) { // test for minimum length if necessary
+ cond = And(cond,
+ GreaterThanOrEquals(
+ typed(
+ Apply(
+ Select(
+ gen.mkAsInstanceOf(selector.duplicate,
+ node.getTpe(),
+ true),
+ node.getTpe().member(nme.length) /*defs.Seq_length*/),
+ List())
+ ),
+ typed(
+ Literal(Constant(minlen))
+ )));
+ }
+ cond
+ },
Block(
List(
ValDef(casted,
gen.mkAsInstanceOf(selector.duplicate, node.getTpe(), true)),
- ValDef(castedRest,
- Apply(
- Select(
- Select(
- gen.mkAsInstanceOf(selector.duplicate, node.getTpe(), true),
- "toList"),
- "drop"),
- List(Literal(Constant(minlen)))))),
+ ValDef(castedRest, {
+ var res:Tree = gen.mkAsInstanceOf(selector.duplicate, node.getTpe(), true);
+ if(minlen != 0) {
+ res = Apply(Select(Select(res, "toList"), "drop"),List(Literal(Constant(minlen))))
+
+ }
+ res
+ })),
toTree(node.and))),
toTree(node.or, selector.duplicate));
diff --git a/test/files/run/regularpatmatnew.check b/test/files/run/regularpatmatnew.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/run/regularpatmatnew.check
diff --git a/test/files/run/regularpatmatnew.scala b/test/files/run/regularpatmatnew.scala
new file mode 100644
index 0000000000..af2dd65d2e
--- /dev/null
+++ b/test/files/run/regularpatmatnew.scala
@@ -0,0 +1,74 @@
+object Test {
+ import scala.testing.SUnit._
+
+ def main(args:Array[String]): Unit = {
+ val tr = new TestResult
+ new TestSuite(
+
+ new Test01,
+ new Test02,
+ new Test03
+
+ ).run(tr)
+
+ for(val f <- tr.failures())
+ Console println f
+ }
+
+ class Test01 extends TestCase("numero uno (all ignoring patterns on List)") {
+ def doMatch(l:List[String]):String = l match {
+ case List(_*) => "ok"
+ }
+ override def runTest() = {
+ val list1 = List();
+ assertEquals(doMatch(list1), "ok");
+ val list2 = List("1","2","3");
+ assertEquals(doMatch(list2), "ok");
+ }
+ }
+
+ /* these are not allowed, for strange reasons I will never figure out
+
+ def doMatch(l:Seq[String]):String = l match {
+ case List(_*) => "ok"
+ case _ => "not ok"
+ }
+
+ def doMatch(l:Seq[String]):String = l match {
+ case Array(_*) => "ok"
+ case _ => "not ok"
+ }
+ */
+
+ class Test02 extends TestCase("numero due (all ignoring patterns on Seq)") {
+ def doMatch(l:Seq[String]):String = l match {
+ case Seq(_*) => "ok"
+ }
+ override def runTest() = {
+ val list1 = List();
+ assertEquals(doMatch(list1), "ok");
+ val list2 = List("1","2","3");
+ assertEquals(doMatch(list2), "ok");
+ val array3 = Array[String]();
+ assertEquals(doMatch(array3), "ok");
+ val array4 = Array[String]("ga","gu");
+ assertEquals(doMatch(array4), "ok");
+ }
+ }
+
+ class Test03 extends TestCase("numero tre (right-ignoring patterns on List, defaults)") {
+ def doMatch(l:List[String]):String = l match {
+ case List(_,_,_,_*) => "ok"
+ case _ => "not ok"
+ }
+ override def runTest() = {
+ val list1 = List();
+ assertEquals(doMatch(list1), "not ok");
+ val list2 = List("1","2","3");
+ assertEquals(doMatch(list2), "ok");
+ val list3 = List("1","2","3","4");
+ assertEquals(doMatch(list3), "ok");
+ }
+ }
+
+}