From 818a2e6597f23a82f848cd1f7d3b2e29129390a6 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 8 Dec 2012 18:15:08 +0100 Subject: SI-6555 Better parameter name retention We were losing track of parameter names in two places: 1. Uncurry was using fresh names for the apply method parameters during Function expansion. (The parameter names in the tree were actually correct, they just had synthetic symbols with "x$1" etc.) 2. When adding specialized overrides, the parameter names of the overriden method were used, rather than the parameter names from the overriding method in the class to which we are adding methods. The upshot of this is that when you're stopped in the debugger in the body of, say, `(i: Int) => i * i`, you see `v1` rather than `i`. This commit changes Uncurry and SpecializeTypes to remedy this. --- .../tools/nsc/transform/SpecializeTypes.scala | 5 +++++ .../scala/tools/nsc/transform/UnCurry.scala | 5 ++++- test/files/neg/t6260.check | 4 ++-- test/files/run/t6555.check | 22 ++++++++++++++++++++++ test/files/run/t6555.scala | 15 +++++++++++++++ 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 test/files/run/t6555.check create mode 100644 test/files/run/t6555.scala diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 2f79472cfb..bbab545d9e 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -965,6 +965,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case (NoSymbol, _) => None case (overridden, env) => val om = specializedOverload(clazz, overridden, env) + foreachWithIndex(om.paramss) { (params, i) => + foreachWithIndex(params) { (param, j) => + param.name = overriding.paramss(i)(j).name // SI-6555 Retain the parameter names from the subclass. + } + } debuglog("specialized overload %s for %s in %s: %s".format(om, overriding.name.decode, pp(env), om.info)) typeEnv(om) = env addConcreteSpecMethod(overriding) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 9829fd0e57..838ea7d5a0 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -251,7 +251,10 @@ abstract class UnCurry extends InfoTransform val applyMethodDef = { val methSym = anonClass.newMethod(nme.apply, fun.pos, FINAL) - methSym setInfoAndEnter MethodType(methSym newSyntheticValueParams formals, restpe) + val paramSyms = map2(formals, fun.vparams) { + (tp, param) => methSym.newSyntheticValueParam(tp, param.name) + } + methSym setInfoAndEnter MethodType(paramSyms, restpe) fun.vparams foreach (_.symbol.owner = methSym) fun.body changeOwner (fun.symbol -> methSym) diff --git a/test/files/neg/t6260.check b/test/files/neg/t6260.check index 2b7f1a8bfb..46e9bd1dfc 100644 --- a/test/files/neg/t6260.check +++ b/test/files/neg/t6260.check @@ -1,10 +1,10 @@ -t6260.scala:3: error: bridge generated for member method apply: (x$1: Box[X])Box[Y] in anonymous class $anonfun +t6260.scala:3: error: bridge generated for member method apply: (bx: Box[X])Box[Y] in anonymous class $anonfun which overrides method apply: (v1: T1)R in trait Function1 clashes with definition of the member itself; both have erased type (v1: Object)Object ((bx: Box[X]) => new Box(f(bx.x)))(this) ^ -t6260.scala:8: error: bridge generated for member method apply: (x$1: Box[X])Box[Y] in anonymous class $anonfun +t6260.scala:8: error: bridge generated for member method apply: (bx: Box[X])Box[Y] in anonymous class $anonfun which overrides method apply: (v1: T1)R in trait Function1 clashes with definition of the member itself; both have erased type (v1: Object)Object diff --git a/test/files/run/t6555.check b/test/files/run/t6555.check new file mode 100644 index 0000000000..04117b7c2f --- /dev/null +++ b/test/files/run/t6555.check @@ -0,0 +1,22 @@ +[[syntax trees at end of specialize]] // newSource1 +package { + class Foo extends Object { + def (): Foo = { + Foo.super.(); + () + }; + private[this] val f: Int => Int = { + @SerialVersionUID(0) final class $anonfun extends scala.runtime.AbstractFunction1$mcII$sp with Serializable { + def (): anonymous class $anonfun = { + $anonfun.super.(); + () + }; + final def apply(param: Int): Int = $anonfun.this.apply$mcII$sp(param); + def apply$mcII$sp(param: Int): Int = param + }; + (new anonymous class $anonfun(): Int => Int) + }; + def f(): Int => Int = Foo.this.f + } +} + diff --git a/test/files/run/t6555.scala b/test/files/run/t6555.scala new file mode 100644 index 0000000000..b1a6137786 --- /dev/null +++ b/test/files/run/t6555.scala @@ -0,0 +1,15 @@ +import scala.tools.partest._ +import java.io.{Console => _, _} + +object Test extends DirectTest { + + override def extraSettings: String = "-usejavacp -Xprint:specialize -d " + testOutput.path + + override def code = "class Foo { val f = (param: Int) => param } " + + override def show(): Unit = { + Console.withErr(System.out) { + compile() + } + } +} -- cgit v1.2.3