Aladdin - Scala Bugtracking
[#1097] project: compiler priority: low category: bug
submitter assigned to status date submitted
Iulian Iulian fixed 2007-05-10 15:54:01.0
subject [contrib #465] Early definitions in object causes runtime exception
code
When using early definitions in an object definition, you get a NullPointerException at runtime. The following code compiles fine:

abstract class B {
  val v: String
}

object A extends {
  val v = "foo"
} with B {}

object Test {

  def main(args: Array[String]) = {
    Console.println(A.v)
  }

}
what happened
When you run Test, you get the following exception:

Exception in thread "main" java.lang.ExceptionInInitializerError
        at Test$.main(Test.scala:12)
        at Test.main(Test.scala)
Caused by: java.lang.NullPointerException
        at A$.(Test.scala:6)
        at A$.(Test.scala)
        ... 2 more
what expected Successful execution
[back to overview]
Changes of this bug report
Martin  edited on  2007-05-11 00:41:13.0
It seems the backend is changing the reference A.this.v = "foo" to A$.MODULE$.v = "foo" Because A$.MODULE is assigned only after the superclass constructor is called we get an NullPointerException. You can verify by printing the constructor of A at phase cleanup (then it looks still OK) and doing a javap afterwards. Question: Why the replacement? Would it not be more efficient in general to keep `this' references?
Iulian  edited on  2007-05-11 16:43:45.0
Fixed. The problem was treating object values too uniformly. Actually the tree is not A.this.v = ... but simply A.v, where A carries the module symbol. The code generator blindly generated the same code for all module references, by reading the MODULE$ field. Now it checks first to see if the module we're accessing is the same as the class we're generating, in which case it replaces it by 'this'.