Skip to content

Fix instability of self variable API representation#2507

Merged
eed3si9n merged 4 commits intosbt:0.13from
gkossakowski:self-variable-unstable
Mar 18, 2016
Merged

Fix instability of self variable API representation#2507
eed3si9n merged 4 commits intosbt:0.13from
gkossakowski:self-variable-unstable

Conversation

@gkossakowski
Copy link
Contributor

The reason for instability is a bit tricky so let's unpack what the previous code checking if there's self type declared was doing. It would check if thisSym of a class is equal to a symbol representing the class. If that's true, we know that there's no self type. If it's false, then thisSym represents either a self type or a self variable. The second (type test) was supposed to check whether the type of thisSym is different from a type of the class. However, it would always yield false because TypeRef of thisSym was compared to ClassInfoType of a class. So if you had a self variable the logic would see a self type (and that's what API representation would give you).

Now the tricky bit: thisSym is not pickled when it's representing just a self variable because self variable doesn't affect other classes referring to a class. If you looked at a type after unpickling, the
symbol equality test would yield true and we would not see self type when just a self variable was declared.

The fix is to check equality of type refs on both side of the type equality check. This makes the pending test passing.

Also, I added another test that checks if self types are represented in various combinations of declaring a self variable or/and self type.

Fixes #2504.

This commit enables control of whether a compiler instance should be reused
between compiling groups of Scala source files. Check comments in the code
for why this can be useful to control.
Add a pending test that shows a problem with instability of representing
self variables. This test covers the bug described in sbt#2504.

In order to test API representation of a class declared either in source
file or unpickled from a class file, ScalaCompilerForUnitTesting has been
extended to extract APIs from multiple compiler instances sharing a
classpath.
The reason for instability is a bit tricky so let's unpack what the
previous code checking if there's self type declared was doing. It would
check if `thisSym` of a class is equal to a symbol representing the class.
If that's true, we know that there's no self type. If it's false, then
`thisSym` represents either a self type or a self variable. The second
(type test) was supposed to check whether the type of `thisSym` is
different from a type of the class. However, it would always yield false
because TypeRef of `thisSym` was compared to ClassInfoType of a class.
So if you had a self variable the logic would see a self type (and that's
what API representation would give you).

Now the tricky bit: `thisSym` is not pickled when it's representing just
a self variable because self variable doesn't affect other classes
referring to a class. If you looked at a type after unpickling, the
symbol equality test would yield true and we would not see self type when
just a self variable was declared.

The fix is to check equality of type refs on both side of the type equality
check. This makes the pending test passing.

Also, I added another test that checks if self types are represented in
various combinations of declaring a self variable or/and self type.

Fixes sbt#2504.
@gkossakowski gkossakowski force-pushed the self-variable-unstable branch from b37bd31 to a6ae339 Compare March 8, 2016 21:24
@gkossakowski
Copy link
Contributor Author

Review by @adriaanm

@gkossakowski gkossakowski added this to the 0.13.12 milestone Mar 8, 2016
@gkossakowski
Copy link
Contributor Author

I think this fix (once reviewed and merged) might warrant a new release. The bug is rather bad because it degrades performance of incremental compiler in a way that's hard to both detect and debug. The counterargument against expedited release would be that it only affects code bases that declare inner classes with self variables.

@eed3si9n
Copy link
Member

eed3si9n commented Mar 8, 2016

We can do a milestone right away so ppl can test it if they run into this.

|}
|""".stripMargin
val src2 =
"""|class Global {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you end up figuring out why nesting was needed to repro?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because you need to inherit a class as a member to have its full API representation. If you just inherit from a class directly, then you're going to have API representation of its members.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks!

@adriaanm
Copy link
Contributor

adriaanm commented Mar 8, 2016

Good stuff, @gkossakowski! Thanks for picking this up.

Per review request, add two more test cases for self variable (no self
type).
@gkossakowski
Copy link
Contributor Author

I added more tests.

@gkossakowski
Copy link
Contributor Author

Ping

@eed3si9n
Copy link
Member

@adriaanm Can I merge it?

@adriaanm
Copy link
Contributor

LGTM, sorry for delay

eed3si9n added a commit that referenced this pull request Mar 18, 2016
Fix instability of self variable API representation
@eed3si9n eed3si9n merged commit 9d666c5 into sbt:0.13 Mar 18, 2016
@eed3si9n
Copy link
Member

@gkossakowski Please forward port this to sbt/zinc.

@gkossakowski
Copy link
Contributor Author

It's part of class-based branch that I'm preparing for merge.

On 18 March 2016 at 17:50, eugene yokota notifications@github.com wrote:

@gkossakowski https://github.com/gkossakowski Please forward port this
to sbt/zinc.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#2507 (comment)

Grzegorz Kossakowski
twitter: @gkossakowski http://twitter.com/gkossakowski
github: @gkossakowski http://github.com/gkossakowski

eed3si9n added a commit to sbt/zinc that referenced this pull request Mar 30, 2016
@eed3si9n eed3si9n mentioned this pull request May 1, 2016
7 tasks
@dwijnand
Copy link
Member

dwijnand commented Sep 6, 2016

Forward port in sbt/zinc#90

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants