Skip to content

Commit b810c92

Browse files
committed
Merge pull request scala#4125 from retronym/ticket/8944
SI-8944 A more resiliant naming scheme for case accessors
2 parents ac5c324 + ff2cd80 commit b810c92

File tree

8 files changed

+41
-1
lines changed

8 files changed

+41
-1
lines changed

src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,14 @@ trait SyntheticMethods extends ast.TreeDSL {
359359

360360
for (ddef @ DefDef(_, _, _, _, _, _) <- templ.body ; if isRewrite(ddef.symbol)) {
361361
val original = ddef.symbol
362-
val newAcc = deriveMethod(ddef.symbol, name => context.unit.freshTermName(name + "$")) { newAcc =>
362+
val i = original.owner.caseFieldAccessors.indexOf(original)
363+
def freshAccessorName = {
364+
devWarning(s"Unable to find $original among case accessors of ${original.owner}: ${original.owner.caseFieldAccessors}")
365+
context.unit.freshTermName(original.name + "$")
366+
}
367+
def nameSuffixedByParamIndex = original.name.append(nme.CASE_ACCESSOR + "$" + i).toTermName
368+
val newName = if (i < 0) freshAccessorName else nameSuffixedByParamIndex
369+
val newAcc = deriveMethod(ddef.symbol, name => newName) { newAcc =>
363370
newAcc.makePublic
364371
newAcc resetFlag (ACCESSOR | PARAMACCESSOR | OVERRIDE)
365372
ddef.rhs.duplicate

src/reflect/scala/reflect/internal/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ trait StdNames {
111111
val PACKAGE: NameType = "package"
112112
val ROOT: NameType = "<root>"
113113
val SPECIALIZED_SUFFIX: NameType = "$sp"
114+
val CASE_ACCESSOR: NameType = "$access"
114115

115116
// value types (and AnyRef) are all used as terms as well
116117
// as (at least) arguments to the @specialize annotation.

test/files/run/t8944/A_1.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
case class A(private val x: String)

test/files/run/t8944/A_2.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
case class Other(private val x: String) // consume a fresh name suffix
2+
3+
// the param accessor will now be called "x$2",
4+
// whereas the previously compiled client expects it to be called
5+
// x$1
6+
case class A(private val x: String)

test/files/run/t8944/Test_1.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test extends App {
2+
val A("") = new A("")
3+
}

test/files/run/t8944b.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
case class A(private var foo: Any) {
2+
def m = { def foo = 42 /*will be lamba lifted to `A#foo$1`*/ }
3+
}
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
val A("") = new A("")
7+
new A("").m
8+
}
9+
}

test/files/run/t8944c.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
private java.lang.Object Foo.ant()
2+
public java.lang.Object Foo.ant$access$0()
3+
private scala.collection.Seq Foo.cat()
4+
public scala.collection.Seq Foo.cat$access$2()
5+
public java.lang.Object Foo.elk()

test/files/run/t8944c.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
case class Foo[A](private val ant: Any, elk: Any, private val cat: A*)
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
def pred(name: String) = Set("ant", "elk", "cat").exists(name contains _)
6+
println(classOf[Foo[_]].getDeclaredMethods.filter(m => pred(m.getName)).sortBy(_.getName).mkString("\n"))
7+
}
8+
}

0 commit comments

Comments
 (0)