-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Local fields are created unnecessarily instead of using existing ones in superclass #608
Comments
The issue is in if (sym is (PrivateLocalParamAccessor, butNot = Mutable)) { Replacing |
scalac is too willing to use the super param accessors, IMO. For example: class A(val aaa: Int)
class B(y: Int) extends A(y) {
def yy = y
}
class C extends B(0) {
override val aaa = ???
}
object Test {
def main(args: Array[String]): Unit = {
new C().yy // throws!
}
} |
@retronym, in your example, shouldn't constructor throw? |
Oh right. The behaviour I'm trying to show is in this case, a separate field is required in class A(val y: Int)
class B(y: Int) extends A(y) {
def yy = y
}
class C extends B(0) {
override val y = -1
}
object Test {
def main(args: Array[String]): Unit = {
println(new C().yy) // prints 0 as expected
}
} |
But, in this case, we print class A(val y: Int)
class B(override val y: Int) extends A(y) {
def yy = y
}
class C extends B(0) {
override val y = -1
}
object Test {
def main(args: Array[String]): Unit = {
println(new C().yy) // prints -1
}
} |
Looks like it is wrong. Which is really unfortunate, because avoid
On Wed, May 27, 2015 at 10:23 AM, Jason Zaugg notifications@github.com
Martin Odersky |
@odersky why is it wrong? C overrides |
Correction: Everything is fine. In fact, here is the disassembled code of B class A(val y: Int) /Users/odersky/workspace/dotty/playground> javap -c -private B public B(int); Note the "invokespecial". That's crucial so that we get the getter of B, public class B extends A { private int y(); public int yy(); I agree that if we have a On Wed, May 27, 2015 at 11:26 AM, Dmitry Petrashko <notifications@github.com
Martin Odersky |
@odersky, so in the example from original post
Should the field be shared? |
Yes, it should be shared. On Wed, May 27, 2015 at 1:34 PM, Dmitry Petrashko notifications@github.com
Martin Odersky |
I have a fix with an extensive test case at https://github.com/smarter/dotty/commits/fix/param-forwarding unfortunately the following currently fail: class A(val aaa: Int)
class B(override val aaa: Int) extends A(aaa) With: try/superarg2.scala:2: error: overriding value aaa in class A of type Int;
method aaa of type => Int needs to be a stable, immutable value
class B(override val aaa: Int) extends A(aaa) The failure comes from } else if (other.isStable && !member.isStable) { // (1.4)
overrideError("needs to be a stable, immutable value") Because at the point where class A(aaa: Int) extends Object() {
val aaa: Int
}
class B(aaa: Int) extends A(aaa) {
override def aaa: Int = super.aaa
} What would be the best way to avoid this? Should I try using |
Also mark the forwarder as Stable otherwise we get a RefChecks error. This fixes scala#608.
Also mark the forwarder as Stable otherwise we get a RefChecks error. This fixes scala#608.
Also mark the forwarder as Stable otherwise we get a RefChecks error. This fixes scala#608. Note that we do less parameter forwarding than scalac. See for example D and Y in paramForwarding.scala which don't get their own local fields in scalac but do in dotty.
Also mark the forwarder as Stable otherwise we get a RefChecks error. This fixes scala#608. Note that we do less parameter forwarding than scalac. See for example D and Y in tests/run/paramForwarding.scala which don't get their own local fields in scalac but do in dotty.
We shouldn't need to define a new local field in
B
here:But we do in dotty:
Compare with scalac:
The text was updated successfully, but these errors were encountered: