Skip to content

problem with @specialized case class if constructor writes to private var #4962

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

Closed
scabug opened this issue Sep 1, 2011 · 5 comments
Closed
Milestone

Comments

@scabug
Copy link

scabug commented Sep 1, 2011

scala> case class Cell[@specialized T](x:T) { private[this] var v = x; def read = v }
residual specialized constructor statements: ListBuffer(Cell$mcV$sp.this.v$mcV$sp = scala.runtime.BoxedUnit.UNIT)
residual specialized constructor statements: ListBuffer(Cell$mcZ$sp.this.v$mcZ$sp = Cell$mcZ$sp.this.x())
residual specialized constructor statements: ListBuffer(Cell$mcB$sp.this.v$mcB$sp = Cell$mcB$sp.this.x())
residual specialized constructor statements: ListBuffer(Cell$mcS$sp.this.v$mcS$sp = Cell$mcS$sp.this.x())
residual specialized constructor statements: ListBuffer(Cell$mcC$sp.this.v$mcC$sp = Cell$mcC$sp.this.x())
residual specialized constructor statements: ListBuffer(Cell$mcI$sp.this.v$mcI$sp = Cell$mcI$sp.this.x())
residual specialized constructor statements: ListBuffer(Cell$mcJ$sp.this.v$mcJ$sp = Cell$mcJ$sp.this.x())
residual specialized constructor statements: ListBuffer(Cell$mcF$sp.this.v$mcF$sp = Cell$mcF$sp.this.x())
residual specialized constructor statements: ListBuffer(Cell$mcD$sp.this.v$mcD$sp = Cell$mcD$sp.this.x())
defined class Cell

scala> Cell(7) read
res5: Int = 0

Result should be 7, not 0. Error is not specific to repl. There is no error if one uses private instead of private[this] and it has to be a case class.

@scabug
Copy link
Author

scabug commented Sep 1, 2011

Imported From: https://issues.scala-lang.org/browse/SI-4962?orig=1
Reporter: @TiarkRompf

@scabug
Copy link
Author

scabug commented Feb 21, 2012

@non said (edited on Feb 21, 2012 5:05:40 AM UTC):
So, the problem here is that specialization does correctly change the private[this] modifier to protected[this], but does not go back and create the appropriate getter/setter methods which scalac would have already created by that point.

You can easily see this by diffing the output of -Xprint:tailcalls between a version using private[this] and a version using private:

11c11,13
<     def read(): T = Cell.this.v;
---
>     private <accessor> def v(): T = Cell.this.v;
>     private <accessor> def v_=(x$1: T): Unit = Cell.this.v = x$1;
>     def read(): T = Cell.this.v();

I'm not sure what the best way to handle this is. I guess we could try to explicitly call the methods which would create the accessors, and then manually rewrite field access to use them? The tough thing is that the logic about which methods will need to be specialized is (currently) quite complicated, so we can't easily move the rewriting code into an earlier phase.

What seems best?

@scabug
Copy link
Author

scabug commented Feb 21, 2012

@non said:
I should add that a really terrible but easy hack would be something like: if you see a specialized class, rewrite all private[this] to private on the assumption that it doesn't change things that much.

I am not endorsing this idea, but it seems a lot easier than correctly creating/using accessors after the fact, or correctly determining which members will need to be specialized on early enough.

@scabug
Copy link
Author

scabug commented Feb 21, 2012

@paulp said:
There are a lot of other bugs with private this, most likely variations on this cause. I think the right thing to do is always create the accessors, and leave them out of the generated class if they weren't used. Too many assumptions made too early in the pipeline make jack a crashy boy.

@scala scala deleted a comment from scabug Mar 2, 2018
@scala scala deleted a comment from scabug Mar 2, 2018
@SethTisue SethTisue added this to the Backlog milestone Mar 2, 2018
@som-snytt
Copy link

Fixed in 2.11.0

@SethTisue SethTisue modified the milestones: Backlog, 2.11.0 May 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants