Skip to content

Commit 09bf956

Browse files
committed
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.
1 parent 85cd96d commit 09bf956

File tree

5 files changed

+40
-5
lines changed

5 files changed

+40
-5
lines changed

src/compiler/scala/tools/nsc/transform/AddInterfaces.scala

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,21 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
257257
/** Transforms the member tree containing the implementation
258258
* into a member of the impl class.
259259
*/
260-
private def implMethodDef(tree: Tree): Tree = (
261-
implMethodMap get tree.symbol
262-
map (impl => new ChangeOwnerAndReturnTraverser(tree.symbol, impl)(tree setSymbol impl))
263-
getOrElse abort("implMethod missing for " + tree.symbol)
264-
)
260+
private def implMethodDef(tree: Tree): Tree = {
261+
val impl = implMethodMap.getOrElse(tree.symbol, abort("implMethod missing for " + tree.symbol))
262+
263+
val newTree = if (impl.isErroneous) tree else { // e.g. res/t687
264+
// SI-5167: Ensure that the tree that we are grafting refers the parameter symbols from the
265+
// new method symbol `impl`, rather than the symbols of the original method signature in
266+
// the trait. `tree setSymbol impl` does *not* suffice!
267+
val DefDef(_, _, _, vparamss, _, _) = tree
268+
val oldSyms = vparamss.flatten.map(_.symbol)
269+
val newSyms = impl.info.paramss.flatten
270+
assert(oldSyms.length == newSyms.length, (oldSyms, impl, impl.info))
271+
tree.substTreeSyms(oldSyms, newSyms)
272+
}
273+
new ChangeOwnerAndReturnTraverser(newTree.symbol, impl)(newTree setSymbol impl)
274+
}
265275

266276
/** Add mixin constructor definition
267277
* def $init$(): Unit = ()

test/files/res/t5167.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
nsc>
3+
nsc>
4+
nsc>

test/files/res/t5167.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
t5167/t5167_1.scala
2+
t5167/t5167_2.scala

test/files/res/t5167/t5167_1.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package compilerbug
2+
3+
trait SadTrait {
4+
def buggyMethod[T](argWithDefault1: Int = 0)(argWithDefault2: String = "default") {
5+
for (i <- 0 to 1) {
6+
val x = argWithDefault1
7+
val y = argWithDefault2
8+
}
9+
}
10+
}
11+
12+
object SadObject extends SadTrait

test/files/res/t5167/t5167_2.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package compilerbug
2+
3+
class TestClass {
4+
def repro() {
5+
SadObject.buggyMethod[Int]()()
6+
}
7+
}

0 commit comments

Comments
 (0)