diff options
author | Paolo Giarrusso <p.giarrusso@gmail.com> | 2012-09-05 02:53:26 +0200 |
---|---|---|
committer | Paolo Giarrusso <p.giarrusso@gmail.com> | 2012-09-12 19:11:52 +0200 |
commit | 9568dc9d1a8e69812f4ec0b72a11a38edaa51f2a (patch) | |
tree | 847ef29de2566c2ab892bc07cf96deda4d06990e /test/files | |
parent | 5415272018114bb2e15036c5d6f9ae9c5af625d2 (diff) | |
download | scala-9568dc9d1a8e69812f4ec0b72a11a38edaa51f2a.tar.gz scala-9568dc9d1a8e69812f4ec0b72a11a38edaa51f2a.tar.bz2 scala-9568dc9d1a8e69812f4ec0b72a11a38edaa51f2a.zip |
SI-6306 Remove incorrect eta-expansion optimization in Uncurry
Fix SI-6306 by removing the offending code. Moreover, clarify comment
and add testcase.
This pattern match only matches on testcases triggering SI-6306; the
transformation it performs in that case is unsafe.
The intended optimization is to undo eta-expansion of nullary functions,
that is, transform `() => foo()` to `foo`. But that's only valid when
`foo` is an instance of `Function0`, so the optimization is unsafe.
Moreover, the pattern match will fail because at the end of typer that
code has become `() => foo.apply()`, and `isExprSafeToInline(foo.apply)`
always (correctly) fails the isExprSafeToInline test. The pattern match
should thus be different - this code was dead even when it was
introduced (45bcd02f6ba099277bedbf83ec2bda07435c7797), since it was not
invoked either when building the compiler or when compiling function
attempt2() in the included testcase.
Thanks to all commenters on SI-6306 and
https://github.com/scala/scala/pull/1255, in particular to Jason Zaugg
for diagnosing the underlying fault and Lukas Rytz for understanding the
goal of the code.
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/run/pure-args-byname-noinline.check | 12 | ||||
-rw-r--r-- | test/files/run/pure-args-byname-noinline.scala | 33 |
2 files changed, 45 insertions, 0 deletions
diff --git a/test/files/run/pure-args-byname-noinline.check b/test/files/run/pure-args-byname-noinline.check new file mode 100644 index 0000000000..a39c61eb64 --- /dev/null +++ b/test/files/run/pure-args-byname-noinline.check @@ -0,0 +1,12 @@ +2 +2 +2 +2 +List(1) +List() + +1 +1 +1 +1 +1 diff --git a/test/files/run/pure-args-byname-noinline.scala b/test/files/run/pure-args-byname-noinline.scala new file mode 100644 index 0000000000..5c5c8a7eb6 --- /dev/null +++ b/test/files/run/pure-args-byname-noinline.scala @@ -0,0 +1,33 @@ +object Test { + //Were affected by SI-6306 + def f[A](a: =>A) = println(a.toString) + def f1[A <: AnyVal](a: =>A) = println(a.toString) + def f1a[A <: AnyVal](a: =>A) = println(a.##) + def f2[A <: AnyRef](a: =>A) = println(a.toString) + def f2a[A <: String](a: =>A) = println(a.toString) + //Works + def f3[A](a: =>Seq[A]) = println(a.toString) + + def foo() = println(2) + def client(f: () => Unit) = {f(); f()} + def attempt2() { + val bar: () => Unit = foo _ + //The code causing SI-6306 was supposed to optimize code like this: + client(() => bar ()) + //to: + client(bar) + } + def main(args: Array[String]) { + attempt2() + f3(Seq(1)) + f3(Seq()) + f("") + f((1).toString) + f((1).##) + f1((1).##) + f2((1).toString) + f2a((1).toString) + } +} + +// vim: set ts=8 sw=2 et: |