diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2012-06-02 13:24:00 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2012-06-03 14:16:54 +0200 |
commit | 09bf95675b06a0912ab1e3c8cdcab9a19eca48d4 (patch) | |
tree | deebbe85cb6a92dbdff4102cdda6f075841354c8 | |
parent | 85cd96da352c929ea0ce4ba236730579e09c5c4b (diff) | |
download | scala-09bf95675b06a0912ab1e3c8cdcab9a19eca48d4.tar.gz scala-09bf95675b06a0912ab1e3c8cdcab9a19eca48d4.tar.bz2 scala-09bf95675b06a0912ab1e3c8cdcab9a19eca48d4.zip |
SI-5167 An impl class method should refer to its own parameter symbols.
Rather than those of the original method in the trait.
If they are shared, parameter renaming in the implementaion class
is visible in the original method. This led to a crash in the resident
compiler when looking up the default argument getter.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/AddInterfaces.scala | 20 | ||||
-rw-r--r-- | test/files/res/t5167.check | 4 | ||||
-rw-r--r-- | test/files/res/t5167.res | 2 | ||||
-rw-r--r-- | test/files/res/t5167/t5167_1.scala | 12 | ||||
-rw-r--r-- | test/files/res/t5167/t5167_2.scala | 7 |
5 files changed, 40 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index e5fc98f23c..8c5d25e6c4 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -257,11 +257,21 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure => /** Transforms the member tree containing the implementation * into a member of the impl class. */ - private def implMethodDef(tree: Tree): Tree = ( - implMethodMap get tree.symbol - map (impl => new ChangeOwnerAndReturnTraverser(tree.symbol, impl)(tree setSymbol impl)) - getOrElse abort("implMethod missing for " + tree.symbol) - ) + private def implMethodDef(tree: Tree): Tree = { + val impl = implMethodMap.getOrElse(tree.symbol, abort("implMethod missing for " + tree.symbol)) + + val newTree = if (impl.isErroneous) tree else { // e.g. res/t687 + // SI-5167: Ensure that the tree that we are grafting refers the parameter symbols from the + // new method symbol `impl`, rather than the symbols of the original method signature in + // the trait. `tree setSymbol impl` does *not* suffice! + val DefDef(_, _, _, vparamss, _, _) = tree + val oldSyms = vparamss.flatten.map(_.symbol) + val newSyms = impl.info.paramss.flatten + assert(oldSyms.length == newSyms.length, (oldSyms, impl, impl.info)) + tree.substTreeSyms(oldSyms, newSyms) + } + new ChangeOwnerAndReturnTraverser(newTree.symbol, impl)(newTree setSymbol impl) + } /** Add mixin constructor definition * def $init$(): Unit = () diff --git a/test/files/res/t5167.check b/test/files/res/t5167.check new file mode 100644 index 0000000000..6cf64f734b --- /dev/null +++ b/test/files/res/t5167.check @@ -0,0 +1,4 @@ + +nsc> +nsc> +nsc> diff --git a/test/files/res/t5167.res b/test/files/res/t5167.res new file mode 100644 index 0000000000..a485cbee41 --- /dev/null +++ b/test/files/res/t5167.res @@ -0,0 +1,2 @@ +t5167/t5167_1.scala +t5167/t5167_2.scala
\ No newline at end of file diff --git a/test/files/res/t5167/t5167_1.scala b/test/files/res/t5167/t5167_1.scala new file mode 100644 index 0000000000..ed28243507 --- /dev/null +++ b/test/files/res/t5167/t5167_1.scala @@ -0,0 +1,12 @@ +package compilerbug + +trait SadTrait { + def buggyMethod[T](argWithDefault1: Int = 0)(argWithDefault2: String = "default") { + for (i <- 0 to 1) { + val x = argWithDefault1 + val y = argWithDefault2 + } + } +} + +object SadObject extends SadTrait diff --git a/test/files/res/t5167/t5167_2.scala b/test/files/res/t5167/t5167_2.scala new file mode 100644 index 0000000000..5aa56efe75 --- /dev/null +++ b/test/files/res/t5167/t5167_2.scala @@ -0,0 +1,7 @@ +package compilerbug + +class TestClass { + def repro() { + SadObject.buggyMethod[Int]()() + } +} |