Skip to content

Commit 13434c0

Browse files
committed
Emit all classes as public to avoid object deserialization issues
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.
1 parent 30ce9a5 commit 13434c0

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,11 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes {
296296
*/
297297
final def javaFlags(sym: Symbol): Int = {
298298

299-
val privateFlag = sym.is(Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass)
299+
// Classes are always emitted as public. This matches the behavior of Scala 2
300+
// and is necessary for object deserialization to work properly, otherwise
301+
// ModuleSerializationProxy may fail with an accessiblity error (see
302+
// tests/run/serialize.scala).
303+
val privateFlag = !sym.isClass && (sym.is(Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass))
300304

301305
val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !sym.is(Mutable) && !sym.enclosingClass.is(Trait)
302306

tests/run/serialize.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
package a {
2+
object Outer extends Serializable {
3+
private object Inner extends Serializable
4+
5+
val inner: AnyRef = Inner
6+
}
7+
class Foo extends Serializable {
8+
val x: AnyRef = Outer.inner
9+
}
10+
}
11+
112
object Test {
213
def serializeDeserialize[T <: AnyRef](obj: T): T = {
314
import java.io.*
@@ -26,5 +37,9 @@ object Test {
2637

2738
val baz = serializeDeserialize(Baz)
2839
assert(baz ne Baz)
40+
41+
val foo = new a.Foo
42+
val foo1 = serializeDeserialize(foo)
43+
assert(foo.x eq foo1.x)
2944
}
3045
}

0 commit comments

Comments
 (0)