diff --git a/community-build/community-projects/scalatest b/community-build/community-projects/scalatest index 9b2479aeb85f..832453cb476d 160000 --- a/community-build/community-projects/scalatest +++ b/community-build/community-projects/scalatest @@ -1 +1 @@ -Subproject commit 9b2479aeb85fe2828c67da9edc6c4688d633a5d3 +Subproject commit 832453cb476d17835b6baffcf384a8d299b4d320 diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 25a05077626a..58e6265376fd 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -296,7 +296,11 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I) extends BTypes { */ final def javaFlags(sym: Symbol): Int = { - val privateFlag = sym.is(Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass) + // 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 and https://github.com/typelevel/cats-effect/pull/2360). + val privateFlag = !sym.isClass && (sym.is(Private) || (sym.isPrimaryConstructor && sym.owner.isTopLevelModuleClass)) val finalFlag = sym.is(Final) && !toDenot(sym).isClassConstructor && !sym.is(Mutable) && !sym.enclosingClass.is(Trait) diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index 73b7e9ca674e..5b57381248f9 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -21,6 +21,11 @@ object MiMaFilters { ProblemFilters.exclude[DirectMissingMethodProblem]("scala.deriving.Mirror.fromTuple"), // Private to the compiler - needed for forward binary compatibility - ProblemFilters.exclude[MissingClassProblem]("scala.annotation.since") + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.since"), + + // Private inner classes, but we emit all classes as public in Java bytecode + ProblemFilters.exclude[InaccessibleClassProblem]("scala.quoted.FromExpr$PrimitiveFromExpr"), + ProblemFilters.exclude[InaccessibleClassProblem]("scala.quoted.Type$ValueOf$"), + ProblemFilters.exclude[InaccessibleClassProblem]("scala.reflect.Selectable$DefaultSelectable"), ) } diff --git a/tests/run/i4404a.check b/tests/run/i4404a.check index 11444aa1f1fe..fa056b1cd9d5 100644 --- a/tests/run/i4404a.check +++ b/tests/run/i4404a.check @@ -1,8 +1,4 @@ -false -false -false -true -false -true -true -true +public class Car +public final class Volvo +public final class Car$ +public static final class Car$$anon$1 diff --git a/tests/run/i4404a.scala b/tests/run/i4404a.scala index b322218cf930..41d5e7064714 100644 --- a/tests/run/i4404a.scala +++ b/tests/run/i4404a.scala @@ -8,12 +8,10 @@ object Car { } object Test { - def main(args: Array[String]) = { - List(new Car, new Volvo, Car, Car.car) - .map(_.getClass.getModifiers) - .foreach { m => - println(Modifier.isPrivate(m)) - println(Modifier.isFinal(m)) - } + def main(args: Array[String]): Unit = { + val l = List(new Car, new Volvo, Car, Car.car) + .map(_.getClass) + .map(cls => s"${Modifier.toString(cls.getModifiers)} $cls") + println(l.mkString("\n")) } } diff --git a/tests/run/i4404b.check b/tests/run/i4404b.check index bb101b641b9b..1d474d525571 100644 --- a/tests/run/i4404b.check +++ b/tests/run/i4404b.check @@ -1,2 +1,2 @@ -true +false true diff --git a/tests/run/serialize.scala b/tests/run/serialize.scala index 0622807bee21..830c2935ac97 100644 --- a/tests/run/serialize.scala +++ b/tests/run/serialize.scala @@ -1,3 +1,14 @@ +package a { + object Outer extends Serializable { + private object Inner extends Serializable + + val inner: AnyRef = Inner + } + class Bar extends Serializable { + val x: AnyRef = Outer.inner + } +} + object Test { def serializeDeserialize[T <: AnyRef](obj: T): T = { import java.io.* @@ -26,5 +37,9 @@ object Test { val baz = serializeDeserialize(Baz) assert(baz ne Baz) + + val bar = new a.Bar + val bar1 = serializeDeserialize(bar) + assert(bar.x eq bar1.x) } }