summaryrefslogtreecommitdiff
path: root/test/files/neg
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-12-15 18:28:03 -0800
committerPaul Phillips <paulp@improving.org>2013-12-15 18:28:03 -0800
commit11bfa25e37d32f4017d5c04b4899b1bdfbd95e06 (patch)
tree42fab30ce189d1bc93fbecb5496448a7176ba5e9 /test/files/neg
parentdbe7a366c994fe359edc368bfcd8a6a35a00e0da (diff)
downloadscala-11bfa25e37d32f4017d5c04b4899b1bdfbd95e06.tar.gz
scala-11bfa25e37d32f4017d5c04b4899b1bdfbd95e06.tar.bz2
scala-11bfa25e37d32f4017d5c04b4899b1bdfbd95e06.zip
SI-7897, SI-6675 improves name-based patmat
This emerges from a recent attempt to eliminate pattern matcher related duplication and to bake the scalac-independent logic out of it. I had in mind something a lot cleaner, but it was a whole lot of work to get it here and I can take it no further. Key file to admire is PatternExpander.scala, which should provide a basis for some separation of concerns. The bugs addressed are a CCE involving Tuple1 and an imprecise warning regarding multiple pattern crushing. Editorial: auto-tupling unapply results was a terrible idea which should never have escaped from the crib. It is tantamount to purposely throwing type safety down the toilet in the very place where people need type safety the most. See SI-6111 and SI-6675 for some other comments.
Diffstat (limited to 'test/files/neg')
-rw-r--r--test/files/neg/t4425b.check30
-rw-r--r--test/files/neg/t5903a.check2
-rw-r--r--test/files/neg/t6675b.check37
-rw-r--r--test/files/neg/t6675b.flags1
-rw-r--r--test/files/neg/t6675b.scala40
-rw-r--r--test/files/neg/t7214neg.check7
-rw-r--r--test/files/neg/t7897.check4
-rw-r--r--test/files/neg/t7897.scala23
-rw-r--r--test/files/neg/t997.check7
9 files changed, 119 insertions, 32 deletions
diff --git a/test/files/neg/t4425b.check b/test/files/neg/t4425b.check
index 1186e8b609..ae7b469d52 100644
--- a/test/files/neg/t4425b.check
+++ b/test/files/neg/t4425b.check
@@ -22,40 +22,28 @@ t4425b.scala:10: error: object X is not a case class constructor, nor does it ha
Note: def unapply(x: String)(y: String): Nothing exists in object X, but it cannot be used as an extractor due to its second non-implicit parameter list
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:18: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:18: error: too many patterns for object X: expected 1, found 2
println( "" match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:19: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:19: error: too many patterns for object X: expected 1, found 2
println((X: Any) match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:22: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:22: error: too many patterns for object X: expected 1, found 2
println( "" match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:22: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
- println( "" match { case X(_, _) => "ok" ; case _ => "fail" })
- ^
-t4425b.scala:23: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:23: error: too many patterns for object X: expected 1, found 2
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:23: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
- println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
- ^
-t4425b.scala:31: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:31: error: too many patterns for object X offering Nothing: expected 1, found 2
println( "" match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:32: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:32: error: too many patterns for object X offering Nothing: expected 1, found 2
println((X: Any) match { case _ X _ => "ok" ; case _ => "fail" })
^
-t4425b.scala:35: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:35: error: too many patterns for object X offering Nothing: expected 1, found 2
println( "" match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:35: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
- println( "" match { case X(_, _) => "ok" ; case _ => "fail" })
- ^
-t4425b.scala:36: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
+t4425b.scala:36: error: too many patterns for object X offering Nothing: expected 1, found 2
println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
^
-t4425b.scala:36: error: wrong number of patterns for object X offering Nothing: expected 1, found 2
- println((X: Any) match { case X(_, _) => "ok" ; case _ => "fail" })
- ^
-18 errors found
+14 errors found
diff --git a/test/files/neg/t5903a.check b/test/files/neg/t5903a.check
index 2e5cc87167..34003b0a82 100644
--- a/test/files/neg/t5903a.check
+++ b/test/files/neg/t5903a.check
@@ -1,4 +1,4 @@
-Test_2.scala:4: error: wrong number of patterns for <$anon: AnyRef> offering (SomeTree.type, SomeTree.type): expected 2, found 3
+Test_2.scala:4: error: too many patterns for <$anon: AnyRef> offering (SomeTree.type, SomeTree.type): expected 2, found 3
case nq"$x + $y + $z" => println((x, y))
^
one error found
diff --git a/test/files/neg/t6675b.check b/test/files/neg/t6675b.check
new file mode 100644
index 0000000000..77f6b3ccbc
--- /dev/null
+++ b/test/files/neg/t6675b.check
@@ -0,0 +1,37 @@
+t6675b.scala:17: warning: object LeftOrRight expects 2 patterns to hold (Int, Int) but crushing into 2-tuple to fit single pattern (SI-6675)
+ def f1 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight(a) => a } // warn
+ ^
+t6675b.scala:19: error: constructor cannot be instantiated to expected type;
+ found : (T1, T2, T3)
+ required: (Int, Int)
+ def f3 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight((a, b, c)) => a } // fail
+ ^
+t6675b.scala:24: warning: object LeftOrRight expects 2 patterns to hold (A, A) but crushing into 2-tuple to fit single pattern (SI-6675)
+ def f2[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight(a) => a } // warn
+ ^
+t6675b.scala:26: error: constructor cannot be instantiated to expected type;
+ found : (T1, T2, T3)
+ required: (?A11, ?A12) where type ?A12 <: A (this is a GADT skolem), type ?A11 <: A (this is a GADT skolem)
+ def f4[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight((a, b, c)) => a } // fail
+ ^
+t6675b.scala:30: warning: object NativelyTwo expects 2 patterns to hold ((Int, Int), (Int, Int)) but crushing into 2-tuple to fit single pattern (SI-6675)
+ def f1 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo(a) => a } // warn
+ ^
+t6675b.scala:32: error: constructor cannot be instantiated to expected type;
+ found : (T1, T2, T3)
+ required: ((Int, Int), (Int, Int))
+ def f3 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo((a, b, c)) => a } // fail
+ ^
+t6675b.scala:36: warning: object NativelyTwo expects 2 patterns to hold (A, A) but crushing into 2-tuple to fit single pattern (SI-6675)
+ def f1[A](x: A) = (Left(x): Either[A, A]) match { case NativelyTwo(a) => a } // warn
+ ^
+t6675b.scala:37: warning: object NativelyTwo expects 2 patterns to hold ((A, A), (A, A)) but crushing into 2-tuple to fit single pattern (SI-6675)
+ def f2[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo(a) => a } // warn
+ ^
+t6675b.scala:39: error: constructor cannot be instantiated to expected type;
+ found : (T1, T2, T3)
+ required: ((?A17, ?A18), (?A19, ?A20)) where type ?A20 <: A (this is a GADT skolem), type ?A19 <: A (this is a GADT skolem), type ?A18 <: A (this is a GADT skolem), type ?A17 <: A (this is a GADT skolem)
+ def f4[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo((a, b, c)) => a } // fail
+ ^
+5 warnings found
+four errors found
diff --git a/test/files/neg/t6675b.flags b/test/files/neg/t6675b.flags
new file mode 100644
index 0000000000..1008b0a70c
--- /dev/null
+++ b/test/files/neg/t6675b.flags
@@ -0,0 +1 @@
+-Xlint
diff --git a/test/files/neg/t6675b.scala b/test/files/neg/t6675b.scala
new file mode 100644
index 0000000000..c86c9c3955
--- /dev/null
+++ b/test/files/neg/t6675b.scala
@@ -0,0 +1,40 @@
+object LeftOrRight {
+ def unapply[A](value: Either[A, A]): Option[A] = value match {
+ case scala.Left(x) => Some(x)
+ case scala.Right(x) => Some(x)
+ }
+}
+
+object NativelyTwo {
+ def unapply[A](value: Either[A, A]): Option[(A, A)] = value match {
+ case scala.Left(x) => Some(x -> x)
+ case scala.Right(x) => Some(x -> x)
+ }
+}
+
+
+class A {
+ def f1 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight(a) => a } // warn
+ def f2 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight((a, b)) => a } // no warn
+ def f3 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case LeftOrRight((a, b, c)) => a } // fail
+}
+
+class B {
+ def f1[A](x: A) = (Left(x): Either[A, A]) match { case LeftOrRight(a) => a } // no warn
+ def f2[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight(a) => a } // warn
+ def f3[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight((a, b)) => a } // no warn
+ def f4[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case LeftOrRight((a, b, c)) => a } // fail
+}
+
+class C {
+ def f1 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo(a) => a } // warn
+ def f2 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo((a, b)) => a } // no warn
+ def f3 = (Left((0, 0)): Either[(Int, Int), (Int, Int)]) match { case NativelyTwo((a, b, c)) => a } // fail
+}
+
+class D {
+ def f1[A](x: A) = (Left(x): Either[A, A]) match { case NativelyTwo(a) => a } // warn
+ def f2[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo(a) => a } // warn
+ def f3[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo((a, b)) => a } // no warn
+ def f4[A](x: A) = (Left(x -> x): Either[(A, A), (A, A)]) match { case NativelyTwo((a, b, c)) => a } // fail
+}
diff --git a/test/files/neg/t7214neg.check b/test/files/neg/t7214neg.check
index 0660cccd02..291af04578 100644
--- a/test/files/neg/t7214neg.check
+++ b/test/files/neg/t7214neg.check
@@ -1,7 +1,4 @@
-t7214neg.scala:28: error: wrong number of patterns for object Extractor offering Any: expected 1, found 0
+t7214neg.scala:28: error: not enough patterns for object Extractor offering Any: expected 1, found 0
case Extractor() =>
^
-t7214neg.scala:28: error: wrong number of patterns for object Extractor offering Any: expected 1, found 0
- case Extractor() =>
- ^
-two errors found
+one error found
diff --git a/test/files/neg/t7897.check b/test/files/neg/t7897.check
new file mode 100644
index 0000000000..48eff511c7
--- /dev/null
+++ b/test/files/neg/t7897.check
@@ -0,0 +1,4 @@
+t7897.scala:19: error: value length is not a member of p0.Single
+ case p0.Single(x) => println(s"`$x` has ${x.length} chars")
+ ^
+one error found
diff --git a/test/files/neg/t7897.scala b/test/files/neg/t7897.scala
new file mode 100644
index 0000000000..87c966b1e0
--- /dev/null
+++ b/test/files/neg/t7897.scala
@@ -0,0 +1,23 @@
+package p0 {
+ class Single(val x: Any) extends AnyRef with Product1[String] {
+ private def s = "" + x
+ override def canEqual(x: Any) = this eq x.asInstanceOf[AnyRef]
+ def isEmpty = false
+ def get = this
+ def _1 = s + " only"
+
+ override def toString = s"Single(${_1})"
+ }
+
+ object Single {
+ def unapply(x: Any): Single = new Single(x)
+ }
+}
+object Test {
+ def main(args: Array[String]): Unit = {
+ "catdog" match {
+ case p0.Single(x) => println(s"`$x` has ${x.length} chars")
+ case x => println("fail: " + x)
+ }
+ }
+}
diff --git a/test/files/neg/t997.check b/test/files/neg/t997.check
index 8c41060ba2..b118792229 100644
--- a/test/files/neg/t997.check
+++ b/test/files/neg/t997.check
@@ -1,7 +1,4 @@
-t997.scala:13: error: wrong number of patterns for object Foo offering (String, String): expected 2, found 3
+t997.scala:13: error: too many patterns for object Foo offering (String, String): expected 2, found 3
"x" match { case Foo(a, b, c) => Console.println((a,b,c)) }
^
-t997.scala:13: error: wrong number of patterns for object Foo offering (String, String): expected 2, found 3
-"x" match { case Foo(a, b, c) => Console.println((a,b,c)) }
- ^
-two errors found
+one error found