Skip to content

Fix #1750: Alternative fix for cyclic references due to illegal class overrides #1913

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

Merged
merged 1 commit into from
Jan 30, 2017

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jan 29, 2017

Illegal class overrides are fundamentally at odds with the way dotty
represents types and therefore can cause lots of low-level problems.

Two measures in this commit:

First, we detect direct illegal class overrides on completion instead of
during RefChecks. Break the override by making the previously
overriding type private.

This fixes i1750.scala, but still fails for indirect overrides between
two unrelated outer traits/classes that are inherited by the same class or trait.
We fix this by catching the previously thrown ClassCastException
in both ExtractAPI and RefChecks.

Test case for indirect overrides is in i1750a.scala.

Review by @liufengyun

@odersky
Copy link
Contributor Author

odersky commented Jan 29, 2017

The CI failure Iis an OOM during dotty bootstrap.

Copy link
Contributor

@liufengyun liufengyun left a comment

Choose a reason for hiding this comment

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

Otherwise, LGTM.

case ex: CyclicReference =>
// See neg/i1750a for an example where a cyclic error can arise.
// The root cause in this example is an illegal "override" of an inner trait
ctx.error(cyclicErrorMsg(ex), base.pos)
Copy link
Contributor

Choose a reason for hiding this comment

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

As a general rule in development, may I understand that try/catch can only be used as the last resort? Just want to know.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's complicated. Cyclic references can only be handled with try-catch, because at the points they are raised we typically do not have a way to back out cleanly. So if a cyclic reference is a possibility we need to handle it with try/catch. And we should try to minimize the places where cyclic references can be raised.

I would think twice before we introduce other exceptions and handle them with try/catch.

class A { // error: classes cannot be overridden
bug()
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

why remove the class here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It now masks the other errors because the error is raised now in typer, whereas the others would be raised in RefChecks.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, it makes sense.

@odersky
Copy link
Contributor Author

odersky commented Jan 29, 2017

We still get an OOM on dotty bootstrapped. @smarter @DarkDimius do we even need this test anymore, now that we bootstrap already as part of the build?

@smarter
Copy link
Member

smarter commented Jan 29, 2017

We still get an OOM on dotty bootstrapped. @smarter @DarkDimius do we even need this test anymore, now that we bootstrap already as part of the build?

Yes, the bootstrap can now be done through sbt, but it still has to be done explicitly by using the dotty-compiler-bootstrapped subproject. This is exactly what partest-only now does, it runs partest inside dotty-compiler-bootstrapped instead of running it inside dotty-compiler.

The OOM we're getting here is similar to what I experienced while working on the sbt bootstrap, I thought I fixed them by increasing the heap size that sbt can use in 239a850, but it looks like it wasn't enough. To recap: the OOM does not happen in one of the forked JVM where we run the tests, instead it happens in the original JVM used by sbt to run its tasks. Since Runtime.getRuntime.availableProcessors returns 40 on our CI, sbt can run up to 40 tasks at the same time, some of these tasks can be compile tasks where scalac compiles dotty, or dotty compiles itself, this easily adds up to a lot of heap usage. We could fix this by reducing the parallelism used by sbt but that would slow down our tests, instead I propose to try increasing the heap used by sbt again. We should also check if running dotty through sbt leaks memory, but that's less urgent.

@smarter
Copy link
Member

smarter commented Jan 29, 2017

... In fact you can disregard everything I said above because this branch is not rebased on top of master, so it should not be using the new sbt-based bootstrap and the new CI settings, I'll rebase it to master and everything should be fine.

Illegal class overrides are fundamentally at odds with the way dotty
represents types and therefore can cause lots of low-level problems.

Two measures in this commit

First, we detect direct illegal class overrides on completion instead of
during RefChecks. Break the override by making the previously
overriding type private.

This fixes i1750.scala, but still fails for indirect overrides between
two unrelated outer traits/classes that are inherited by the same class or trait.
We fix this by catching the previously thrown ClassCastException
in both ExtractAPI and RefChecks.

Test case for indirect overrides is in i1750a.scala.
@odersky
Copy link
Contributor Author

odersky commented Jan 30, 2017

@smarter Thanks for rebasing!

@odersky odersky merged commit d087448 into scala:master Jan 30, 2017
@allanrenucci allanrenucci deleted the fix-#1750 branch December 14, 2017 16:59
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.

3 participants