@@ -59,9 +59,14 @@ object Scala2Unpickler {
59
59
denot.info = PolyType .fromParams(denot.owner.typeParams, denot.info)
60
60
}
61
61
62
- def ensureConstructor (cls : ClassSymbol , scope : Scope )(using Context ): Unit = {
62
+ def ensureConstructor (cls : ClassSymbol , clsDenot : ClassDenotation , scope : Scope )(using Context ): Unit = {
63
63
if (scope.lookup(nme.CONSTRUCTOR ) == NoSymbol ) {
64
64
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 )
65
70
addConstructorTypeParams(constr)
66
71
cls.enter(constr, scope)
67
72
}
@@ -95,7 +100,7 @@ object Scala2Unpickler {
95
100
if (tsym.exists) tsym.setFlag(TypeParam )
96
101
else denot.enter(tparam, decls)
97
102
}
98
- if (! denot.flagsUNSAFE.isAllOf(JavaModule )) ensureConstructor(denot.symbol.asClass , decls)
103
+ if (! denot.flagsUNSAFE.isAllOf(JavaModule )) ensureConstructor(cls, denot, decls)
99
104
100
105
val scalacCompanion = denot.classSymbol.scalacLinkedClass
101
106
@@ -465,11 +470,13 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
465
470
denot.setFlag(flags)
466
471
denot.resetFlag(Touched ) // allow one more completion
467
472
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 ))
473
480
denot.setFlag(NoInits )
474
481
475
482
denot.setPrivateWithin(privateWithin)
0 commit comments