Skip to content

Pretend that BoxedUnit does not extend java.io.Serializable. #9454

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
Jul 28, 2020

Conversation

sjrd
Copy link
Member

@sjrd sjrd commented Jul 28, 2020

Unit does not extend Serializable, but scala.runtime.BoxedUnit does. Because of that, erasing SomeSerializable | Unit yields java.io.Serializable instead of Object.

This is problematic for Scala.js, because the run-time representation of () in Scala.js is not BoxedUnit (which is a JVM artifact) but the JavaScript value undefined, the only instance of java.lang.Void. The latter however does not extend java.io.Serializable, so trying to assign () to a SomeSerializable | Unit will result in invalid IR that fails to pass the IR checker.

We solve this issue by patching the parents of BoxedUnit during unpickling to remove java.io.Serializable. This is done in the same way as adding parents to Tuple classes.

@sjrd sjrd requested a review from smarter July 28, 2020 12:22
Copy link
Member

@dottybot dottybot left a comment

Choose a reason for hiding this comment

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

Hello, and thank you for opening this PR! 🎉

All contributors have signed the CLA, thank you! ❤️

Commit Messages

We want to keep history, but for that to actually be useful we have
some rules on how to format our commit messages (relevant xkcd).

Please stick to these guidelines for commit messages:

  1. Separate subject from body with a blank line
  2. When fixing an issue, start your commit message with Fix #<ISSUE-NBR>:
  3. Limit the subject line to 72 characters
  4. Capitalize the subject line
  5. Do not end the subject line with a period
  6. Use the imperative mood in the subject line ("Add" instead of "Added")
  7. Wrap the body at 80 characters
  8. Use the body to explain what and why vs. how

adapted from https://chris.beams.io/posts/git-commit

Have an awesome day! ☀️

val normalizedParents =
if (fromScala2) defn.adjustForTuple(cls, tparams, parents1)
else parents1 // We are setting the info of a Java class, so it cannot be one of the tuple classes
else defn.adjustForBoxedUnit(cls, parents1)
Copy link
Member

Choose a reason for hiding this comment

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

This adjustment also needs to be done in the Namer (like adjustForTuple) since we typecheck BoxedUnit.java when compiling the standard library

Copy link
Member Author

Choose a reason for hiding this comment

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

Is this really how it works in Dotty? Because in scala/scala, BoxedUnit.java is compiled by Java first, and then its .class file is used when compiling the .scala sources of the stdlib. I don't think BoxedUnit.java is ever processed by scalac. Is the case with dotc?

Copy link
Member

Choose a reason for hiding this comment

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

It's going to depend on how the project is built. I see the build.sbt of scala/scala sets compileOrder := CompileOrder.JavaThenScala but we don't do that in the dotty repo nor in our tests, so I wouldn't rely on it.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK. Done ;)

@sjrd sjrd force-pushed the scalajs-fix-unit-not-serializable-ir-error branch from 8675927 to 829368e Compare July 28, 2020 12:39
Unit does not extend Serializable, but scala.runtime.BoxedUnit
does. Because of that, erasing `SomeSerializable | Unit` yields
`java.io.Serializable` instead of `Object`.

This is problematic for Scala.js, because the run-time
representation of `()` in Scala.js is *not* `BoxedUnit` (which is
a JVM artifact) but the JavaScript value `undefined`, the only
instance of `java.lang.Void`. The latter however does not extend
`java.io.Serializable`, so trying to assign `()` to a
`SomeSerializable | Unit` will result in invalid IR that fails to
pass the IR checker.

We solve this issue by patching the parents of `BoxedUnit` during
unpickling to remove `java.io.Serializable`. This is done in the
same way as adding parents to Tuple classes.
@sjrd sjrd force-pushed the scalajs-fix-unit-not-serializable-ir-error branch from 829368e to 1bd7d2e Compare July 28, 2020 13:22
@sjrd sjrd merged commit bc4b401 into scala:master Jul 28, 2020
@sjrd sjrd deleted the scalajs-fix-unit-not-serializable-ir-error branch July 28, 2020 14:28
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