Aladdin - Scala Bugtracking
[#464] project: nsc priority: medium category: bug
submitter assigned to status date submitted
Iulian _ fixed 2005-10-26 15:32:50.0
subject Non-local super calls are not lifted
code
class A {
  def transform() = ();
}

class B extends A {
  def atPhase(str: String)(bl: => Unit): Unit = bl;

  override def transform() = {
    atPhase("0")(super.transform());
  }
}
what happened
The call to 'super.transform()' should refer to B.super, but after the closure gets created and lifted, super wi\
ll be interpreted as anonfun0.super, which of course, does not contain a transform method. This is a tricky thin\
g, because super calls have to be made from a subclass of the 'desired' class (in this case, somewhere in B).
what expected I think a scheme similar to what is done for mixins. Or, forbid super calls in closures, the same way 'return' are not allowed in scalac.
[back to overview]
Changes of this bug report
Iulian  edited on  2005-10-26 16:14:21.0
Iulian  edited on  2005-10-27 09:49:33.0
I think this should make things a bit clearer. Here's the output of scalac after erasure, for the given example: class B$class() extends A$class() with B() { override def transform(): void = B$class.this.atPhase("0", { ; new $anon$0[].(B$class.this) }); final def B$access$super$A$transform(): void = B$class.super.transform(); } class $anon$0() extends Any() with Function0() { final def apply(): void = $anon$0.this.B$$anon$0$outer$B.B$access$super$A$transform(); (I erased uninteresting parts). On this example, scalac creates a super accessor method in B, which is called by the closer's apply method. NSC does nothing special about super. I think scalac's behavior is the right one.
Iulian  edited on  2005-11-04 10:36:45.0