Skip to content

Conversation

@jackkoenig
Copy link

This is a redo of #1284 or a revert of the revert in #1462.

Fixes #598.

The key observation is that while #1284 used any member references, this only uses inheritance.

I am pretty confident that this will also introduce some overcompilation, so I am specifically asking for help in identifying that and reducing it. That being said, I have had issues with Zinc since #1462 so I wanted to get the ball rolling on fixing those issues and this seemed like a good place to start.

I also contributed some unit tests that I found useful while developing, but they may be redundant with the tests from #598 being re-enabled.

@eed3si9n
Copy link
Member

Thanks for getting this ball rolling again! Really like the thoughtfulness of the PR description.

val dependentOnRemovedClasses = removedClasses.flatMap(previous.memberRef.internal.reverse)
val modifiedClasses = classNames(modifiedSrcs)
val invalidatedClasses = removedClasses ++ dependentOnRemovedClasses ++ modifiedClasses
val inheritanceInvalidations = modifiedClasses.flatMap(previous.inheritance.internal.reverse)
Copy link
Member

Choose a reason for hiding this comment

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

I haven't carefully studied how the bug is occurring, or why this would fix it, but in theory the inheritance relationship is already captured as dependency relationship in Zinc. So if changing

abstract class A

to

trait A

is causing undercompilation, I wonder if we need to enrich the invalidation, specifically when the parent type changes its definition type, as if the signature has changed. The fact that this fixes the bug, but doesn't include information about the trait-vs-class I suspect that it's also might be source of potential problem.

Copy link
Author

Choose a reason for hiding this comment

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

The bug in #598 isn't a typical undercompilation, it's crashing during the incremental compilation. This crash is sort of due to undercompilation in that if you include the right file in the incremental compilation it doesn't occur (thus why this "fix" fixes it), but it's also possible Zinc would figure it out in a later cycle if it didn't crash.

The failure mode if you back out this "fix" and run test I added "recompile subclass when superclass changes from abstract class to trait" is long so I've put it in a gist: https://gist.github.com/jackkoenig/ce190c77fda3e571d43bbe6d6534a327

Copy link
Member

Choose a reason for hiding this comment

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

I see, so:

  1. class B extends trait A, compile both.
  2. change A to abstract class A, and compile only A.scala, scala.tools.nsc.backend.jvm.BTypes crashes with "Bad/Invalid superClass" error.
  3. compiling both B.scala and A.scala would fix the error, but always invalidating all child classes creates overcompilation, since recompilation would happen even for body code changes.

As a workaround, I wonder if we can allow Bad/Invalid superClass error only for the compile cycle 1.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Changing abstract class to trait causes "invalid superClass"

2 participants