@@ -95,7 +95,7 @@ object RefChecks {
9595 * and required classes. Also check that only `enum` constructs extend
9696 * `java.lang.Enum`.
9797 */
98- private def checkParents (cls : Symbol )(using Context ): Unit = cls.info match {
98+ private def checkParents (cls : Symbol , parentTrees : List [ Tree ] )(using Context ): Unit = cls.info match {
9999 case cinfo : ClassInfo =>
100100 def checkSelfConforms (other : ClassSymbol , category : String , relation : String ) = {
101101 val otherSelf = other.declaredSelfTypeAsSeenFrom(cls.thisType)
@@ -109,12 +109,26 @@ object RefChecks {
109109 for (reqd <- cinfo.cls.givenSelfType.classSymbols)
110110 checkSelfConforms(reqd, " missing requirement" , " required" )
111111
112+ def isClassExtendingJavaEnum =
113+ ! cls.isOneOf(Enum | Trait ) && parents.exists(_.classSymbol == defn.JavaEnumClass )
114+
112115 // Prevent wrong `extends` of java.lang.Enum
113- if ! migrateTo3 &&
114- ! cls.isOneOf(Enum | Trait ) &&
115- parents.exists(_.classSymbol == defn.JavaEnumClass )
116- then
117- report.error(CannotExtendJavaEnum (cls), cls.sourcePos)
116+ if isClassExtendingJavaEnum then
117+ if ! migrateTo3 then // always error, only traits or enum-syntax is possible under scala 3.x
118+ report.error(CannotExtendJavaEnum (cls), cls.sourcePos)
119+ else
120+ // conditionally error, we allow classes to extend java.lang.Enum in scala 2 migration mode,
121+ // however the no-arg constructor is forbidden, we must look at the parent trees to see
122+ // which overload is called.
123+ val javaEnumCtor = defn.JavaEnumClass .primaryConstructor
124+ parentTrees.exists {
125+ case parent @ tpd.Apply (tpd.TypeApply (fn, _), _) if fn.tpe.termSymbol eq javaEnumCtor =>
126+ // here we are simulating the error for missing arguments to a constructor.
127+ report.error(JavaEnumParentArgs (parent.tpe), cls.sourcePos)
128+ true
129+ case _ =>
130+ false
131+ }
118132
119133 case _ =>
120134 }
@@ -1089,7 +1103,7 @@ class RefChecks extends MiniPhase { thisPhase =>
10891103 override def transformTemplate (tree : Template )(using Context ): Tree = try {
10901104 val cls = ctx.owner.asClass
10911105 checkOverloadedRestrictions(cls)
1092- checkParents(cls)
1106+ checkParents(cls, tree.parents )
10931107 if (cls.is(Trait )) tree.parents.foreach(checkParentPrefix(cls, _))
10941108 checkCompanionNameClashes(cls)
10951109 checkAllOverrides(cls)
0 commit comments