-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Emit all classes as public to avoid object deserialization issues #14686
Conversation
For reference, all classes in Scala 2 are public in the backend because of this line: https://github.com/scala/scala/blob/ce95d6ca26179e5c189c2b1b40e68d4bc8738cfe/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala#L391 |
13434c0
to
2f717a4
Compare
Technically this isn't a forward-compatible ABI change, but since these classes aren't really part of our public API I think it's fine to ignore that: Error: scala3-library-bootstrapped: Failed binary compatibility check against org.scala-lang:scala3-library_3:3.1.1! Found 3 potential problems (filtered 697)
Error: * private class scala.quoted.FromExpr#PrimitiveFromExpr is inaccessible in other version, it must be public. |
2f717a4
to
fee60fb
Compare
After scala/scala3#14686, Scala 3 emits all classes (even local classes) as public, just like Scala 2. But unlike Scala 2, the local class TestSpec in XmlSocketReporterSpec will be emitted with a zero-argument constructor (in Scala 2 its constructor takes an XmlSocketReporterSpec outer parameter which is never used which seems like a bug). This matters because Scalatest considers a test suite "rerunnable" if it has a zero argument public constructor. So to get the test suite to pass, we need to check for the presence of this constructor just like SuiteRerunner does.
fee60fb
to
86b239a
Compare
// Classes are always emitted as public. This matches the behavior of Scala 2 | ||
// and is necessary for object deserialization to work properly, otherwise | ||
// ModuleSerializationProxy may fail with an accessiblity error (see | ||
// tests/run/serialize.scala). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add a reference to the issue as well?
Yes, this is fine. It will also apply in libraries that have a forward compatibility policy, but in those libraries there should also only be a difference for Scala-private classes, which would be ignorable there as well. |
86b239a
to
05dfcff
Compare
After scala/scala3#14686, Scala 3 emits all classes (even local classes) as public, just like Scala 2. But unlike Scala 2, the local class TestSpec in XmlSocketReporterSpec will be emitted with a zero-argument constructor (in Scala 2 its constructor takes an XmlSocketReporterSpec outer parameter which is never used which seems like a bug). This matters because Scalatest considers a test suite "rerunnable" if it has a zero argument public constructor. So to get the test suite to pass, we need to check for the presence of this constructor just like SuiteRerunner does.
After scala/scala3#14686, Scala 3 emits all classes (even local classes) as public, just like Scala 2. But unlike Scala 2, the local class TestSpec in XmlSocketReporterSpec will be emitted with a zero-argument constructor (in Scala 2 its constructor takes an XmlSocketReporterSpec outer parameter which is never used which seems like a bug). This matters because Scalatest considers a test suite "rerunnable" if it has a zero argument public constructor. So to get the test suite to pass, we need to check for the presence of this constructor just like SuiteRerunner does.
05dfcff
to
30961f5
Compare
This aligns our behavior with Scala 2 and fixes the issue encountered in typelevel/cats-effect#2360 (comment). Alternatively, we could change ModuleSerializationProxy upstream to call `setAccessible(true)` on the MODULE$ field, but this wouldn't work if the object in question is inside a Java 9+ module.
30961f5
to
5e6a3cf
Compare
After scala/scala3#14686, Scala 3 emits all classes (even local classes) as public, just like Scala 2. But unlike Scala 2, the local class TestSpec in XmlSocketReporterSpec will be emitted with a zero-argument constructor (in Scala 2 its constructor takes an XmlSocketReporterSpec outer parameter which is never used which seems like a bug). This matters because Scalatest considers a test suite "rerunnable" if it has a zero argument public constructor. So to get the test suite to pass, we need to check for the presence of this constructor just like SuiteRerunner does.
This aligns our behavior with Scala 2 and fixes the issue encountered in
typelevel/cats-effect#2360 (comment).
Alternatively, we could change ModuleSerializationProxy upstream to call
setAccessible(true)
on the MODULE$ field, but this wouldn't work if the objectin question is inside a Java 9+ module.