diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-10-12 23:40:15 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-10-14 10:00:18 +0200 |
commit | 4f1a46c98afeeb57bd79d339c2be3280cdb41273 (patch) | |
tree | f5a3b167fa364d03a865b031daec84020978c763 /test | |
parent | 810ce7e2790e4da4e3f1d9473ccad5a721847096 (diff) | |
download | scala-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')
-rw-r--r-- | test/files/run/t7899-regression.check | 1 | ||||
-rw-r--r-- | test/files/run/t7899-regression.flags | 1 | ||||
-rw-r--r-- | test/files/run/t7899-regression.scala | 24 |
3 files changed, 26 insertions, 0 deletions
diff --git a/test/files/run/t7899-regression.check b/test/files/run/t7899-regression.check new file mode 100644 index 0000000000..602b03a1d1 --- /dev/null +++ b/test/files/run/t7899-regression.check @@ -0,0 +1 @@ +warning: -Yinfer-by-name is deprecated: This flag is scheduled for removal in 2.12. If you have a case where you need this flag then please report a bug. diff --git a/test/files/run/t7899-regression.flags b/test/files/run/t7899-regression.flags new file mode 100644 index 0000000000..553a27eafd --- /dev/null +++ b/test/files/run/t7899-regression.flags @@ -0,0 +1 @@ +-Yinfer-by-name -deprecation 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) + } +} |