diff options
author | Lukas Rytz <lukas.rytz@epfl.ch> | 2012-05-13 22:43:06 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@epfl.ch> | 2012-05-15 23:39:39 +0200 |
commit | e33901084242b4d7cd76a9279430d0cbc9b9a152 (patch) | |
tree | 63c1c848ca0561f82b769af0fafc35036ec04751 | |
parent | b3f7bc996b7a59b951cd0f199a056b6ad99d153b (diff) | |
download | scala-e33901084242b4d7cd76a9279430d0cbc9b9a152.tar.gz scala-e33901084242b4d7cd76a9279430d0cbc9b9a152.tar.bz2 scala-e33901084242b4d7cd76a9279430d0cbc9b9a152.zip |
Fix for SI-5610
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala | 16 | ||||
-rw-r--r-- | test/files/run/t5610.check | 6 | ||||
-rw-r--r-- | test/files/run/t5610.scala | 30 |
3 files changed, 47 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala index 92ce0e6de4..e1fb683aa9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -63,15 +63,18 @@ trait EtaExpansion { self: Analyzer => * @return ... */ def liftoutPrefix(tree: Tree): Tree = { - def liftout(tree: Tree): Tree = + def liftout(tree: Tree, byName: Boolean): Tree = if (treeInfo.isExprSafeToInline(tree)) tree else { val vname: Name = freshName() // Problem with ticket #2351 here defs += atPos(tree.pos) { - ValDef(Modifiers(SYNTHETIC), vname.toTermName, TypeTree(), tree) + val rhs = if (byName) Function(List(), tree) else tree + ValDef(Modifiers(SYNTHETIC), vname.toTermName, TypeTree(), rhs) + } + atPos(tree.pos.focus) { + if (byName) Apply(Ident(vname), List()) else Ident(vname) } - Ident(vname) setPos tree.pos.focus } val tree1 = tree match { // a partial application using named arguments has the following form: @@ -85,11 +88,14 @@ trait EtaExpansion { self: Analyzer => defs ++= stats liftoutPrefix(fun) case Apply(fn, args) => - treeCopy.Apply(tree, liftoutPrefix(fn), args mapConserve (liftout)) setType null + val byName = fn.tpe.params.map(p => definitions.isByNameParamType(p.tpe)) + // zipAll: with repeated params, there might be more args than params + val newArgs = args.zipAll(byName, EmptyTree, false) map { case (arg, byN) => liftout(arg, byN) } + treeCopy.Apply(tree, liftoutPrefix(fn), newArgs) setType null case TypeApply(fn, args) => treeCopy.TypeApply(tree, liftoutPrefix(fn), args) setType null case Select(qual, name) => - treeCopy.Select(tree, liftout(qual), name) setSymbol NoSymbol setType null + treeCopy.Select(tree, liftout(qual, false), name) setSymbol NoSymbol setType null case Ident(name) => tree } diff --git a/test/files/run/t5610.check b/test/files/run/t5610.check new file mode 100644 index 0000000000..023f18d8f1 --- /dev/null +++ b/test/files/run/t5610.check @@ -0,0 +1,6 @@ +some string +some string +some string +some string +List(2, 3) +List(5, 6) diff --git a/test/files/run/t5610.scala b/test/files/run/t5610.scala new file mode 100644 index 0000000000..f62b2df6b4 --- /dev/null +++ b/test/files/run/t5610.scala @@ -0,0 +1,30 @@ +object Test { + def main(args: Array[String]): Unit = { + var test: String = null + val fun1: Int => () => Unit = foo(test) _ + val fun2: Int => () => Unit = foo(test)(_) + val fun3: Int => () => Unit = { + lazy val eta1: String = test + (dummy: Int) => foo(eta1)(dummy) + } + val fun4: Int => () => Unit = { + val eta1: () => String = () => test + (dummy: Int) => foo(eta1())(dummy) + } + test = "some string" + fun1(1)() + fun2(1)() + fun3(1)() + fun4(1)() + + val f: (String, Int*) => Unit = m(2, 3) + f("", 5, 6) + } + + def foo(s: => String)(dummy: Int) = () => println(s) + + def m(a: Int*)(z: String, b: Int*) { + println(a.toList) + println(b.toList) + } +} |