-
Notifications
You must be signed in to change notification settings - Fork 394
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
Name clash for $outer pointers of two different nesting levels #2382
Comments
Found out that the second variant can be minimized further to: trait A {
val a: Int = 1
class X
}
trait B extends A {
class Y {
def y: Int = 2
class Z extends X {
def z1: Int = a
def z3: Int = y
}
}
} |
Further minimization to: trait A {
val a: Int = 1
class X
class Y {
class Z extends X {
def b: Int = a
}
}
} And the issue does not manifest itself with the def main() {
val b = new A { }
val y = new b.Y
val z = new y.Z
assertEquals(1, b.a, "b.a")
assertEquals(1, z.b, "z.b")
} will produce $c_Lhelloworld_HelloWorld$.prototype.main__V = (function() {
var b = new $c_Lhelloworld_HelloWorld$$anon$1().init___();
var y = new $c_Lhelloworld_A$Y().init___Lhelloworld_A(b);
var z = new $c_Lhelloworld_A$Y$Z().init___Lhelloworld_A$Y(y);
this.assertEquals__I__I__T__V(1, b.a$1, "b.a");
this.assertEquals__I__I__T__V(1, z.b__I(), "z.b")
}); which fails with
|
With the optimizer disabled the failure shows itself on a missing
|
As a deserialization hack, we mangle all Scala fields that are called `$$outer$f`, i.e., those that were `protected val $outer` in scalac. We mangle them with their type, which is always locally known (in `FieldDef`s and `Select`s, which are the only two IR nodes dealing with Scala fields). This almost fixes the name clashes. It is still possible to have a clash for classes that are nested in the same class, but for those, all the clashing `$outer` pointers must have the same value, and so the clash is not a problem in practice. For `$outer` pointers at different levels of nesting, which are the ones that were causing scala-js#2382, the type of the `$outer` pointers must be different, by construction. The mangling by type therefore always distinguishes them.
So the fix in PR #2384 proved to be binary incompatible, so that doesn't work. Consequently, I imagined a link-time hack to disambiguate So basically, we're stuck. This fix will have to wait for a binary breaking release, i.e., 1.0.0. |
The root cause of the bug scala-js#2625 which surfaces in 2.12.0 is actually scala-js#2382. We cannot fix scala-js#2382 without breaking backwards binary compatibility in general. However, we can fix it only for 2.12.0-RC2 onwards, as RCs of Scala (and the upcoming final) have separate binary ecosystems anyway. So this commit fixes scala-js#2382 but only for 2.12.0-RC2 onwards. The fix is trivial: name mangle all outer pointers with the fully qualified enclosing class.
The root cause of the bug scala-js#2625 which surfaces in 2.12.0 is actually scala-js#2382. We cannot fix scala-js#2382 without breaking backwards binary compatibility in general. However, we can fix it only for 2.12.0-RC2 onwards, as RCs of Scala (and the upcoming final) have separate binary ecosystems anyway. So this commit fixes scala-js#2382 but only for 2.12.0-RC2 onwards. The fix is trivial: name mangle all outer pointers with the fully qualified enclosing class.
The root cause of the bug scala-js#2625 which surfaces in 2.12.0 is actually scala-js#2382. We cannot fix scala-js#2382 without breaking backwards binary compatibility in general. However, we can fix it only for 2.12.0-RC2 onwards, as RCs of Scala (and the upcoming final) have separate binary ecosystems anyway. So this commit fixes scala-js#2382 but only for 2.12.0-RC2 onwards. The fix is trivial: name mangle all outer pointers in the same way as if they were private, i.e., with the number of class ancestors of its owner.
This issue closed automatically, but in fact it's still not fixed for Scala 2.10.x and 2.11.x, so reopening. |
We simply remove the guard that prevented the fix from being applied in 2.10 and 2.11. It was necessary in 0.6.x not to break backward binary compatibility, but we can now fix it for good.
We simply remove the guard that prevented the fix from being applied in 2.10 and 2.11. It was necessary in 0.6.x not to break backward binary compatibility, but we can now fix it for good.
Fix #2382 for good, on all Scala versions.
As minimized by @nicolasstucki:
The text was updated successfully, but these errors were encountered: