summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-09-27 06:41:17 -0700
committerPaul Phillips <paulp@improving.org>2012-09-27 09:24:04 -0700
commit96d4a8646b1962fac2f2fc443b56c6619221b43c (patch)
treebd39f411275452bb5db2335da966ac8042cd504f /test
parent17b409b7832f541e3d52d2776c8ff3c47574ae0f (diff)
downloadscala-96d4a8646b1962fac2f2fc443b56c6619221b43c.tar.gz
scala-96d4a8646b1962fac2f2fc443b56c6619221b43c.tar.bz2
scala-96d4a8646b1962fac2f2fc443b56c6619221b43c.zip
Nailed down the "impossible match" logic.
I will again defer to a comment. /** Given classes A and B, can it be shown that nothing which is * an A will ever be a subclass of something which is a B? This * entails not only showing that !(A isSubClass B) but that the * same is true of all their subclasses. Restated for symmetry: * the same value cannot be a member of both A and B. * * 1) A must not be a subclass of B, nor B of A (the trivial check) * 2) One of A or B must be completely knowable (see isKnowable) * 3) Assuming A is knowable, the proposition is true if * !(A' isSubClass B) for all A', where A' is a subclass of A. * * Due to symmetry, the last condition applies as well in reverse. */
Diffstat (limited to 'test')
-rw-r--r--test/files/neg/patmat-type-check.check10
-rw-r--r--test/files/neg/t1872.check4
-rw-r--r--test/files/neg/unchecked-abstract.check25
-rw-r--r--test/files/neg/unchecked-abstract.flags1
-rw-r--r--test/files/neg/unchecked-abstract.scala93
-rw-r--r--test/files/neg/unchecked-impossible.check4
-rw-r--r--test/files/neg/unchecked-impossible.flags1
-rw-r--r--test/files/neg/unchecked-impossible.scala16
-rw-r--r--test/files/neg/unchecked-knowable.check4
-rw-r--r--test/files/neg/unchecked-knowable.flags1
-rw-r--r--test/files/neg/unchecked-knowable.scala20
-rw-r--r--test/files/neg/unchecked2.check12
12 files changed, 185 insertions, 6 deletions
diff --git a/test/files/neg/patmat-type-check.check b/test/files/neg/patmat-type-check.check
index e045841ce1..721217c314 100644
--- a/test/files/neg/patmat-type-check.check
+++ b/test/files/neg/patmat-type-check.check
@@ -1,3 +1,12 @@
+patmat-type-check.scala:11: warning: fruitless type test: a value of type Test.Bop4[T] cannot also be a Seq[A]
+ def s3[T](x: Bop4[T]) = x match { case Seq('b', 'o', 'b') => true }
+ ^
+patmat-type-check.scala:15: warning: fruitless type test: a value of type Test.Bop5[_$1,T1,T2] cannot also be a Seq[A]
+ def s4[T1, T2](x: Bop5[_, T1, T2]) = x match { case Seq('b', 'o', 'b') => true }
+ ^
+patmat-type-check.scala:19: warning: fruitless type test: a value of type Test.Bop3[T] cannot also be a Seq[A]
+ def f4[T](x: Bop3[T]) = x match { case Seq('b', 'o', 'b') => true }
+ ^
patmat-type-check.scala:22: error: scrutinee is incompatible with pattern type;
found : Seq[A]
required: String
@@ -18,4 +27,5 @@ patmat-type-check.scala:30: error: scrutinee is incompatible with pattern type;
required: Test.Bop3[Char]
def f4[T](x: Bop3[Char]) = x match { case Seq('b', 'o', 'b') => true } // fail
^
+three warnings found
four errors found
diff --git a/test/files/neg/t1872.check b/test/files/neg/t1872.check
index ef84ef79e0..c5dc2a8080 100644
--- a/test/files/neg/t1872.check
+++ b/test/files/neg/t1872.check
@@ -1,4 +1,8 @@
+t1872.scala:3: warning: fruitless type test: a value of type Int cannot also be a scala.util.Random
+ def f(x: Int) = x.isInstanceOf[util.Random]
+ ^
t1872.scala:3: error: isInstanceOf cannot test if value types are references.
def f(x: Int) = x.isInstanceOf[util.Random]
^
+one warning found
one error found
diff --git a/test/files/neg/unchecked-abstract.check b/test/files/neg/unchecked-abstract.check
new file mode 100644
index 0000000000..dc7a8d93d0
--- /dev/null
+++ b/test/files/neg/unchecked-abstract.check
@@ -0,0 +1,25 @@
+unchecked-abstract.scala:16: error: abstract type H in type Con[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ ^
+unchecked-abstract.scala:21: error: abstract type H in type Con[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ ^
+unchecked-abstract.scala:27: error: abstract type T in type Inv[M.this.T] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ ^
+unchecked-abstract.scala:28: error: abstract type L in type Inv[M.this.L] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ ^
+unchecked-abstract.scala:31: error: abstract type H in type Inv[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ ^
+unchecked-abstract.scala:33: error: abstract type L in type Inv[M.this.L] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ ^
+unchecked-abstract.scala:36: error: abstract type H in type Inv[M.this.H] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ ^
+unchecked-abstract.scala:37: error: abstract type T in type Inv[M.this.T] is unchecked since it is eliminated by erasure
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ ^
+8 errors found
diff --git a/test/files/neg/unchecked-abstract.flags b/test/files/neg/unchecked-abstract.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked-abstract.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked-abstract.scala b/test/files/neg/unchecked-abstract.scala
new file mode 100644
index 0000000000..5b915755f4
--- /dev/null
+++ b/test/files/neg/unchecked-abstract.scala
@@ -0,0 +1,93 @@
+trait Con[-X]
+trait Inv[X]
+trait Cov[+X]
+
+abstract class M {
+ type H
+ type L <: H
+ type T >: L <: H
+
+ def h1(x: Con[H]) = {
+ /* nowarn */ println(x.isInstanceOf[Con[H]])
+ /* nowarn */ println(x.isInstanceOf[Con[T]])
+ /* nowarn */ println(x.isInstanceOf[Con[L]])
+ }
+ def h2(x: Con[T]) = {
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ /* nowarn */ println(x.isInstanceOf[Con[T]])
+ /* nowarn */ println(x.isInstanceOf[Con[L]])
+ }
+ def h3(x: Con[L]) = {
+ /* warn */ println(x.isInstanceOf[Con[H]])
+ /* warn */ println(x.isInstanceOf[Con[T]])
+ /* nowarn */ println(x.isInstanceOf[Con[L]])
+ }
+ def h4(x: Inv[H]) = {
+ /* nowarn */ println(x.isInstanceOf[Inv[H]])
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ }
+ def h5(x: Inv[T]) = {
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ /* nowarn */ println(x.isInstanceOf[Inv[T]])
+ /* warn */ println(x.isInstanceOf[Inv[L]])
+ }
+ def h6(x: Inv[L]) = {
+ /* warn */ println(x.isInstanceOf[Inv[H]])
+ /* warn */ println(x.isInstanceOf[Inv[T]])
+ /* nowarn */ println(x.isInstanceOf[Inv[L]])
+ }
+ def h7(x: Cov[H]) = {
+ /* nowarn */ println(x.isInstanceOf[Cov[H]])
+ /* warn */ println(x.isInstanceOf[Cov[T]])
+ /* warn */ println(x.isInstanceOf[Cov[L]])
+ }
+ def h8(x: Cov[T]) = {
+ /* nowarn */ println(x.isInstanceOf[Cov[H]])
+ /* nowarn */ println(x.isInstanceOf[Cov[T]])
+ /* warn */ println(x.isInstanceOf[Cov[L]])
+ }
+ def h9(x: Cov[L]) = {
+ /* nowarn */ println(x.isInstanceOf[Cov[H]])
+ /* nowarn */ println(x.isInstanceOf[Cov[T]])
+ /* nowarn */ println(x.isInstanceOf[Cov[L]])
+ }
+}
+
+object Test extends M {
+ type H = Any
+ type T = Int
+ type L = Nothing
+
+ val conh = new Con[H] { }
+ val cont = new Con[T] { }
+ val conl = new Con[L] { }
+
+ val invh = new Inv[H] { }
+ val invt = new Inv[T] { }
+ val invl = new Inv[L] { }
+
+ val covh = new Cov[H] { }
+ val covt = new Cov[T] { }
+ val covl = new Cov[L] { }
+
+ def main(args: Array[String]): Unit = {
+ h1(conh)
+ h2(conh)
+ h2(cont)
+ h3(conh)
+ h3(cont)
+ h3(conl)
+
+ h4(invh)
+ h5(invt)
+ h6(invl)
+
+ h7(covh)
+ h7(covt)
+ h7(covl)
+ h8(covt)
+ h8(covl)
+ h9(covl)
+ }
+}
diff --git a/test/files/neg/unchecked-impossible.check b/test/files/neg/unchecked-impossible.check
new file mode 100644
index 0000000000..0ab371dbaa
--- /dev/null
+++ b/test/files/neg/unchecked-impossible.check
@@ -0,0 +1,4 @@
+unchecked-impossible.scala:5: error: fruitless type test: a value of type T2[Int,Int] cannot also be a Seq[A]
+ case Seq(x) =>
+ ^
+one error found
diff --git a/test/files/neg/unchecked-impossible.flags b/test/files/neg/unchecked-impossible.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked-impossible.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked-impossible.scala b/test/files/neg/unchecked-impossible.scala
new file mode 100644
index 0000000000..985a2d0b08
--- /dev/null
+++ b/test/files/neg/unchecked-impossible.scala
@@ -0,0 +1,16 @@
+final case class T2[+A, +B](a: A, b: B)
+
+class A {
+ def f1 = T2(1, 2) match {
+ case Seq(x) =>
+ case _ =>
+ }
+ def f2 = T2(1, 2) match {
+ case _: T2[Int, Int] => /* nowarn */
+ case _ =>
+ }
+ def f3 = T2(1, 2) match {
+ case _: T2[_, Int] => /* nowarn */
+ case _ =>
+ }
+}
diff --git a/test/files/neg/unchecked-knowable.check b/test/files/neg/unchecked-knowable.check
new file mode 100644
index 0000000000..3a6ef994b5
--- /dev/null
+++ b/test/files/neg/unchecked-knowable.check
@@ -0,0 +1,4 @@
+unchecked-knowable.scala:17: error: fruitless type test: a value of type Bippy cannot also be a A1
+ /* warn */ (new Bippy).isInstanceOf[A1]
+ ^
+one error found
diff --git a/test/files/neg/unchecked-knowable.flags b/test/files/neg/unchecked-knowable.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/neg/unchecked-knowable.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/neg/unchecked-knowable.scala b/test/files/neg/unchecked-knowable.scala
new file mode 100644
index 0000000000..667b47f504
--- /dev/null
+++ b/test/files/neg/unchecked-knowable.scala
@@ -0,0 +1,20 @@
+/** Knowable - only final leaves */
+sealed abstract class A1
+sealed abstract class A2 extends A1
+final class A3 extends A1
+final class A4 extends A2
+
+/** Unknowable */
+sealed abstract class B1
+sealed abstract class B2 extends B1
+final class B3 extends B1
+trait B4 extends B2
+
+class Bippy
+trait Dingus
+
+class A {
+ /* warn */ (new Bippy).isInstanceOf[A1]
+ /* nowarn */ (new Bippy).isInstanceOf[B1]
+ /* nowarn */ ((new Bippy): Any).isInstanceOf[A1]
+}
diff --git a/test/files/neg/unchecked2.check b/test/files/neg/unchecked2.check
index b4a14358c7..68fdfa82ac 100644
--- a/test/files/neg/unchecked2.check
+++ b/test/files/neg/unchecked2.check
@@ -1,22 +1,22 @@
-unchecked2.scala:4: error: fruitless type test: a Some[List[Int]] can never be a Option[List[String]] (but still might match its erasure)
+unchecked2.scala:4: error: fruitless type test: a value of type Some[List[Int]] cannot also be a Option[List[String]] (but still might match its erasure)
/* warn */ Some(List(1)).isInstanceOf[Option[List[String]]]
^
unchecked2.scala:5: error: non-variable type argument Option[_] in type Option[Option[_]] is unchecked since it is eliminated by erasure
/* warn */ Some(123).isInstanceOf[Option[Option[_]]]
^
-unchecked2.scala:6: error: fruitless type test: a Some[Int] can never be a Option[String] (but still might match its erasure)
+unchecked2.scala:6: error: fruitless type test: a value of type Some[Int] cannot also be a Option[String] (but still might match its erasure)
/* warn */ Some(123).isInstanceOf[Option[String]]
^
-unchecked2.scala:7: error: fruitless type test: a Some[Int] can never be a Option[List[String]] (but still might match its erasure)
+unchecked2.scala:7: error: fruitless type test: a value of type Some[Int] cannot also be a Option[List[String]] (but still might match its erasure)
/* warn */ Some(123).isInstanceOf[Option[List[String]]]
^
-unchecked2.scala:8: error: fruitless type test: a Some[Int] can never be a Option[List[Int => String]] (but still might match its erasure)
+unchecked2.scala:8: error: fruitless type test: a value of type Some[Int] cannot also be a Option[List[Int => String]] (but still might match its erasure)
/* warn */ Some(123).isInstanceOf[Option[List[Int => String]]]
^
-unchecked2.scala:9: error: fruitless type test: a Some[Int] can never be a Option[(String, Double)] (but still might match its erasure)
+unchecked2.scala:9: error: fruitless type test: a value of type Some[Int] cannot also be a Option[(String, Double)] (but still might match its erasure)
/* warn */ Some(123).isInstanceOf[Option[(String, Double)]]
^
-unchecked2.scala:10: error: fruitless type test: a Some[Int] can never be a Option[String => Double] (but still might match its erasure)
+unchecked2.scala:10: error: fruitless type test: a value of type Some[Int] cannot also be a Option[String => Double] (but still might match its erasure)
/* warn */ Some(123).isInstanceOf[Option[String => Double]]
^
unchecked2.scala:14: error: non-variable type argument List[String] in type Option[List[String]] is unchecked since it is eliminated by erasure