@@ -59,9 +59,14 @@ object Scala2Unpickler {
5959 denot.info = PolyType .fromParams(denot.owner.typeParams, denot.info)
6060 }
6161
62- def ensureConstructor (cls : ClassSymbol , scope : Scope )(using Context ): Unit = {
62+ def ensureConstructor (cls : ClassSymbol , clsDenot : ClassDenotation , scope : Scope )(using Context ): Unit = {
6363 if (scope.lookup(nme.CONSTRUCTOR ) == NoSymbol ) {
6464 val constr = newDefaultConstructor(cls)
65+ // Scala 2 traits have a constructor iff they have initialization code
66+ // In dotc we represent that as !StableRealizable, which is also owner.is(NoInits)
67+ if clsDenot.flagsUNSAFE.is(Trait ) then
68+ constr.setFlag(StableRealizable )
69+ clsDenot.setFlag(NoInits )
6570 addConstructorTypeParams(constr)
6671 cls.enter(constr, scope)
6772 }
@@ -95,7 +100,7 @@ object Scala2Unpickler {
95100 if (tsym.exists) tsym.setFlag(TypeParam )
96101 else denot.enter(tparam, decls)
97102 }
98- if (! denot.flagsUNSAFE.isAllOf(JavaModule )) ensureConstructor(denot.symbol.asClass , decls)
103+ if (! denot.flagsUNSAFE.isAllOf(JavaModule )) ensureConstructor(cls, denot, decls)
99104
100105 val scalacCompanion = denot.classSymbol.scalacLinkedClass
101106
@@ -465,11 +470,13 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
465470 denot.setFlag(flags)
466471 denot.resetFlag(Touched ) // allow one more completion
467472
468- // Temporary measure, as long as we do not read these classes from Tasty.
469- // Scala-2 classes don't have NoInits set even if they are pure. We override this
470- // for Product and Serializable so that case classes can be pure. A full solution
471- // requires that we read all Scala code from Tasty.
472- if (owner == defn.ScalaPackageClass && ((name eq tpnme.Serializable ) || (name eq tpnme.Product )))
473+ // Temporary measure, as long as we do not recompile these traits with Scala 3.
474+ // Scala 2 is more aggressive when it comes to defining a $init$ method than Scala 3.
475+ // Any concrete definition, even a `def`, causes a trait to receive a $init$ method
476+ // to be created, even if it does not do anything, and hence causes not have the NoInits flag.
477+ // We override this for Product so that cases classes can be pure.
478+ // A full solution requires that we compile Product with Scala 3 in the future.
479+ if (owner == defn.ScalaPackageClass && (name eq tpnme.Product ))
473480 denot.setFlag(NoInits )
474481
475482 denot.setPrivateWithin(privateWithin)
0 commit comments