Skip to content

Separate compilation goes wrong with private object or private lazy val in trait #1140

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

Closed
smarter opened this issue Mar 3, 2016 · 0 comments

Comments

@smarter
Copy link
Member

smarter commented Mar 3, 2016

A_1.scala:

trait A {
  val foo = 0 + x
  private lazy val x = 1
}

B_2.scala:

object B extends A {
  def main(args: Array[String]): Unit = {
    println(foo)
  }
}
% ./bin/dotc A_1.scala
% ./bin/dotc B_2.scala
% scala B
java.lang.NoSuchMethodError: A.A$$x()I
        at B$.<init>(B.scala:1)
        at B$.<clinit>(B.scala)
        at B.main(B.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)

Here's what A.class looks like when we compile A_1.scala and B_2.scala together:

public interface A {
    default public void $init$() {
    }

    public int foo();

    default public int initial$foo() {
        return 0 + this.A$$x();
    }

    default public int A$$x() {
        return 1;
    }
}

and here's what it looks like when we just compile A_1.scala:

public interface A {
    default public void $init$() {
    }

    public int foo();

    default public int initial$foo() {
        return 0 + this.x();
    }

    default private int x() {
        return 1;
    }
}

(Decompilation done using http://www.benf.org/other/cfr/)

odersky added a commit to dotty-staging/dotty that referenced this issue Mar 10, 2016
smarter referenced this issue Mar 13, 2016
Make sure lazy accessors in traits are not private.
smarter added a commit to smarter/sbt that referenced this issue May 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants