aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2017-03-15 18:21:02 +0100
committerGuillaume Martres <smarter@ubuntu.com>2017-03-16 01:00:34 +0100
commit90c1a5f97db02d4af1a6e05f79285c5229f74702 (patch)
tree9f0653ae570572788cca2ddc1ee096465bc9938b /tests
parentc321653cee9f4596b046efdbb8c1913509fec5ef (diff)
downloaddotty-90c1a5f97db02d4af1a6e05f79285c5229f74702.tar.gz
dotty-90c1a5f97db02d4af1a6e05f79285c5229f74702.tar.bz2
dotty-90c1a5f97db02d4af1a6e05f79285c5229f74702.zip
Fix #2099: avoid loading a private member when recomputing a NamedType denot
ParamForwarding creates the following forwarder in B: private[this] def member: Int = super.member Where the type for `super.member` is `TermRef(SubA, member)` and the symbol is the `val member` in `A`. So far this is correct, but in later phases we might call `loadDenot` on this `TermRef` which will end up calling `asMemberOf`, which before this commit just did: prefix.member(name) This is incorrect in our case because `SubA` also happens to have a private `def member`, which means that our forwarder in B now forwards to a private method in a superclass, this subsequently crashes in `ExpandPrivate`. (Note: in the bytecode, a private method cannot have the same name as an overriden method, but this is already worked around in EnsurePrivate.) The fix is simple: when we recompute a member, we should only look at private members if the previous denotation was private.
Diffstat (limited to 'tests')
-rw-r--r--tests/run/paramForwarding_separate.check6
-rw-r--r--tests/run/paramForwarding_separate/A_1.scala3
-rw-r--r--tests/run/paramForwarding_separate/B_2.scala19
3 files changed, 28 insertions, 0 deletions
diff --git a/tests/run/paramForwarding_separate.check b/tests/run/paramForwarding_separate.check
new file mode 100644
index 000000000..8df0c3100
--- /dev/null
+++ b/tests/run/paramForwarding_separate.check
@@ -0,0 +1,6 @@
+# Fields in A:
+private final int A.member$$local
+# Fields in SubA:
+
+# Fields in B:
+
diff --git a/tests/run/paramForwarding_separate/A_1.scala b/tests/run/paramForwarding_separate/A_1.scala
new file mode 100644
index 000000000..7e01f3ef1
--- /dev/null
+++ b/tests/run/paramForwarding_separate/A_1.scala
@@ -0,0 +1,3 @@
+class A(val member: Int)
+
+class SubA(member: Int) extends A(member)
diff --git a/tests/run/paramForwarding_separate/B_2.scala b/tests/run/paramForwarding_separate/B_2.scala
new file mode 100644
index 000000000..774967101
--- /dev/null
+++ b/tests/run/paramForwarding_separate/B_2.scala
@@ -0,0 +1,19 @@
+class B(member: Int) extends SubA(member)
+
+object Test {
+ def printFields(cls: Class[_]) =
+ println(cls.getDeclaredFields.map(_.toString).sorted.deep.mkString("\n"))
+
+ def main(args: Array[String]): Unit = {
+ val a = new A(10)
+ val subA = new SubA(11)
+ val b = new B(12)
+
+ println("# Fields in A:")
+ printFields(classOf[A])
+ println("# Fields in SubA:")
+ printFields(classOf[SubA])
+ println("# Fields in B:")
+ printFields(classOf[B])
+ }
+}