summaryrefslogtreecommitdiff
path: root/test/files/neg/t2066.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-11-22 18:35:43 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-11-27 09:09:46 +0100
commit28d3390e07715b0dcb5ce2f68d72d5a44e6ca74d (patch)
tree8ac9461aa99fd6a2d6b7a937d0459ed8b9c84653 /test/files/neg/t2066.scala
parent073ebbd20ce9775260b83a78ecf9ed6a3e6d3d9e (diff)
downloadscala-28d3390e07715b0dcb5ce2f68d72d5a44e6ca74d.tar.gz
scala-28d3390e07715b0dcb5ce2f68d72d5a44e6ca74d.tar.bz2
scala-28d3390e07715b0dcb5ce2f68d72d5a44e6ca74d.zip
SI-2066 Plug a soundness hole higher order type params, overriding
PolyType-s parameterized by higher order type parameters (HOTPs) should only be relatable with <:< or =:= if the variances of their type parameters line up. This is only enforced for HOTPs defined in method type arguments. Invariant type parameters subsume variant ones. Concretely, as described by @S11001001: > A method taking [F[_]] can implement a method taking [F[+_]]. > Likewise, a method taking [F[_[+_]]] can implement a method > taking [F[_[_]]], as with [F[_[_[_]]]] implementing [F[_[_[+_]]]], > and so on, the variance subsumption flipping at each step. > > This is just the opposite of the variance for passing type > parameters to either instantiate types or call methods; a F[+_] > is a suitable F[_]-argument, a F[_[_]] a suitable F[_[+_]]-argument, > and so on. > > All of the above rules can be duplicated for contravariant positions > by substituting - for +. Also, something similar happens for > weakening/strengthening bounds, I believe. These cases are tested in the `// okay` lines in `neg/t2066.scala`.
Diffstat (limited to 'test/files/neg/t2066.scala')
-rw-r--r--test/files/neg/t2066.scala70
1 files changed, 70 insertions, 0 deletions
diff --git a/test/files/neg/t2066.scala b/test/files/neg/t2066.scala
new file mode 100644
index 0000000000..7f15d39c67
--- /dev/null
+++ b/test/files/neg/t2066.scala
@@ -0,0 +1,70 @@
+trait A1 {
+ def f[T[_]] = ()
+}
+
+trait B1 extends A1 {
+ override def f[T[+_]] = ()
+}
+
+trait C1 extends A1 {
+ override def f[T[-_]] = ()
+}
+
+
+trait A2 {
+ def f[T[+_]] = ()
+}
+
+trait B2 extends A2 {
+ override def f[T[_]] = () // okay
+}
+
+trait C2 extends A2 {
+ override def f[T[-_]] = ()
+}
+
+
+trait A3 {
+ def f[T[-_]] = ()
+}
+
+trait B3 extends A3 {
+ override def f[T[_]] = () // okay
+}
+
+trait C3 extends A3 {
+ override def f[T[-_]] = ()
+}
+
+
+trait A4 {
+ def f[T[X[+_]]] = ()
+}
+
+trait B4 extends A4 {
+ override def f[T[X[_]]] = ()
+}
+
+trait A5 {
+ def f[T[X[-_]]] = ()
+}
+
+trait B5 extends A5 {
+ override def f[T[X[_]]] = ()
+}
+
+
+
+trait A6 {
+ def f[T[X[_]]] = ()
+}
+
+trait B6 extends A6 {
+ override def f[T[X[+_]]] = () // okay
+}
+trait C6 extends A6 {
+ override def f[T[X[_]]] = () // okay
+}
+trait D6 extends A6 {
+ override def f[T[X[-_]]] = ()
+}