summaryrefslogtreecommitdiff
path: root/test/files/run/t7899-regression.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-10-12 23:40:15 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-10-14 10:00:18 +0200
commit4f1a46c98afeeb57bd79d339c2be3280cdb41273 (patch)
treef5a3b167fa364d03a865b031daec84020978c763 /test/files/run/t7899-regression.scala
parent810ce7e2790e4da4e3f1d9473ccad5a721847096 (diff)
downloadscala-4f1a46c98afeeb57bd79d339c2be3280cdb41273.tar.gz
scala-4f1a46c98afeeb57bd79d339c2be3280cdb41273.tar.bz2
scala-4f1a46c98afeeb57bd79d339c2be3280cdb41273.zip
SI-7899 Allow by-name inference under -Yinfer-by-name
As usual, the hole has been exploited in the wild. While you can't abstract over by-name-ness without running into the ClassCastException or an un-applied Function0, there are cases like the enclosed test where you can tiptoe around those cases. I've proposed a small change to Scalaz to avoid tripping over this problem: https://github.com/scalaz/scalaz/pull/562/files But this commit I've also added a transitional flag, -Yinfer-by-name, that they could use to back-publish older versions without code changes. It is also an insurance policy for other projects that might be exploiting the same hole.
Diffstat (limited to 'test/files/run/t7899-regression.scala')
-rw-r--r--test/files/run/t7899-regression.scala24
1 files changed, 24 insertions, 0 deletions
diff --git a/test/files/run/t7899-regression.scala b/test/files/run/t7899-regression.scala
new file mode 100644
index 0000000000..67d38cdd1d
--- /dev/null
+++ b/test/files/run/t7899-regression.scala
@@ -0,0 +1,24 @@
+import language.higherKinds
+
+object Test {
+ trait Monad[M[_]] {
+ def foo[A](ma: M[A])(f: M[A] => Any) = f(ma)
+ }
+ implicit def function1Covariant[T]: Monad[({type l[a] = (T => a)})#l] =
+ new Monad[({type l[a] = (T => a)})#l] {}
+
+ def main(args: Array[String]) {
+ // inference of T = (=> Any) here was outlawed by SI-7899 / 8ed7099
+ // but this pattern is used in Scalaz in just a few places and caused
+ // a regression.
+ //
+ // Inference of a by-name type doesn't *always* lead to a ClassCastException,
+ // it only gets there if a method in generic code accepts a parameter of
+ // that type.
+ //
+ // We need to introduce the stricter inference rules gradually, probably
+ // with a warning.
+ val m = implicitly[Monad[({type f[+x] = (=> Any) => x})#f]]
+ assert(m.foo[Int]((x => 0))(f => f(???)) == 0)
+ }
+}