Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

private[this] def which shadows superclass def is incorrectly called, resulting in IllegalAccessError #9334

Closed
scabug opened this issue May 28, 2015 · 2 comments · Fixed by scala/scala#9542
Labels
access backend fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) has PR typer
Milestone

Comments

@scabug
Copy link

scabug commented May 28, 2015

This compiles fine:

class A {
  def aaa: Int = 10
}
class B extends A {
  private[this] def aaa: Int = 42
}

object Test {
  def main(args: Array[String]): Unit = {
    val b = new B
    println(b.aaa)
  }
}

But explodes at runtime:

java.lang.IllegalAccessError: tried to access method B.aaa()I from class Test$
        at Test$.main(superarg3.scala:12)
        at Test.main(superarg3.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:70)
        at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
        at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:101)
        at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:70)
        at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
        at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
        at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
        at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
        at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
        at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:65)
        at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:87)
        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

Note that dotty seems to do the correct thing here (that is, print "10").

@scabug
Copy link
Author

scabug commented May 28, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9334?orig=1
Reporter: Guillaume Martres (Smarter)
Affected Versions: 2.11.6

@som-snytt
Copy link

There is related discussion at scala/scala@765eb29 concerning the type of the receiver.

Apparently, dotty inherits the previous art, which was amended because of binary compatibility in Java (which disallows reducing the visibility of the method). (The compatibility issue is that moving a method to a superclass shouldn't matter because the receiver type is always the subclass.)

Maybe it suffices to pick the method owner as receiver type only in case of a private name conflict. Or pick the narrowest type possible that also avoids a conflict?

What if I refactor by renaming the private member B.aaa and introducing an override? Is that just defined to be binary incompatible? What if another superclass introduces an override?

It seems to me the easiest fix is to name-mangle the private member. Is it possible to do that in a well-mannered way? Perhaps, mangle only in case of a name conflict, and always for private[this]. (Avoids breaking reflective invocation by name, and private[this] is future-proof against brittle inheritance.)

@SethTisue SethTisue added this to the Backlog milestone Jul 9, 2018
@dwijnand dwijnand added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Feb 15, 2021
@lrytz lrytz added the has PR label Mar 12, 2021
@lrytz lrytz modified the milestones: Backlog, 2.13.6 Mar 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
access backend fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) has PR typer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants