Aladdin - Scala Bugtracking
[#160] project: compiler priority: high category: bug
submitter assigned to status date submitted
Burak Philippe fixed 2003-09-30 12:25:52.0
subject backend handling of constructors
code
class Foo(s:String) {

  def this() = { this("DEFAULT") }

  // not sure whether an earlier phase should have done something
}
what happened
Exception in thread "main" java.lang.AssertionError: void -> java.lang.Object
	at scalac.backend.jvm.GenJVM.genWidenConversion(GenJVM.java:927)
	at scalac.backend.jvm.GenJVM.genLoad(GenJVM.java:559)
	at scalac.backend.jvm.GenJVM.genLoad(GenJVM.java:228)
	at scalac.backend.jvm.GenJVM.genLoadQualifier(GenJVM.java:593)
	at scalac.backend.jvm.GenJVM.genLoad(GenJVM.java:249)
	at scalac.backend.jvm.GenJVM.gen(GenJVM.java:165)
	at scalac.backend.jvm.GenJVM.gen(GenJVM.java:199)
	at scalac.backend.jvm.GenJVM.gen(GenJVM.java:143)
	at scalac.backend.jvm.GenJVM.gen(GenJVM.java:138)
	at scalac.backend.jvm.GenJVM.translate(GenJVM.java:110)
	at scalac.backend.jvm.GenJVMPhase.apply(GenJVMPhase.java:45)
	at scalac.Global.compile(Global.java:293)
	at scalac.Global.compile(Global.java:266)
	at scalac.Main.main(Main.java:32)
what expected silent run.
[back to overview]
Changes of this bug report
Michel  edited on  2003-09-30 14:11:27.0
The problem here, as Philippe and I view it, is that the return type of secondary constructors is not void, as we think it should, but rather the type of the constructed class. (In our views, constructors return nothing, they just initialise the instance they get as argument, as witnessed by calls to super-constructors).

This fact means that erasure adds a cast, which is invalid. Here is for example how a slightly modified version of your example looks like before and after erasure:

[[Trees after phase expandmixins]]
// Scala source: bug_160.scala
interface Foo() extends java.lang.Object();
class Foo$class(s: scala.Int) extends Object() with Foo() {
  def Foo$class(): Foo$class = {
    Foo$class(1)
  }
};

[[Trees after phase erasure]]
// Scala source: bug_160.scala
interface Foo() extends java.lang.Object();
class Foo$class(s: int) extends Object() with Foo() {
  def Foo$class(): Foo$class = {
    Foo$class(1)
  }.asInstanceOf[Foo$class]()
};
The wrong part is the asInstanceOf in the last (code) line.

To solve this problem, we think the cleanest solution is to change the return type of secondary constructors to void. Otherwise, erasure could also be hacked. We have to discuss that together.

Martin  edited on  2003-10-06 10:33:59.0
For type-checking reasons, the return type of constructors needs to be the type of the constructed class. So, the only option we have is to fix erasure.
Philippe  edited on  2003-10-15 11:26:08.0

Moved AddConstructors before Erasure. Modified code of added initializers to avoid cast added in erasure that crashed backend.

Philippe  edited on  2003-10-15 11:26:45.0

Changed status