Skip to content

Commit 93b9361

Browse files
committed
reject more classes extending enums, simplify check
1 parent 70e1fed commit 93b9361

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,6 @@ class Definitions {
651651
@tu lazy val Enum_ordinal: Symbol = EnumClass.requiredMethod(nme.ordinal)
652652

653653
@tu lazy val EnumValuesClass: ClassSymbol = requiredClass("scala.runtime.EnumValues")
654-
@tu lazy val EnumValueClass: ClassSymbol = requiredClass("scala.runtime.EnumValue")
655654

656655
@tu lazy val EnumValueSerializationProxyClass: ClassSymbol = requiredClass("scala.runtime.EnumValueSerializationProxy")
657656
@tu lazy val EnumValueSerializationProxyConstructor: TermSymbol =

compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,9 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
382382
else
383383
Nil
384384

385+
/** Is this an anonymous class deriving from an enum definition? */
385386
extension (cls: ClassSymbol) private def isEnumValueImplementation(using Context): Boolean =
386-
derivesFrom(defn.EnumValueClass) && classParents.exists(_.typeSymbol.flags.is(Enum))
387+
isAnonymousClass && classParents.head.typeSymbol.is(Enum) // asserted in Typer
387388

388389
/** If this is the class backing a serializable singleton enum value with base class `MyEnum`,
389390
* and not deriving from `java.lang.Enum` add the method:

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,9 +1084,10 @@ trait Checking {
10841084
*/
10851085
def checkEnum(cdef: untpd.TypeDef, cls: Symbol, firstParent: Symbol)(using Context): Unit = {
10861086
def isEnumAnonCls =
1087-
cls.isAnonymousClass &&
1088-
cls.owner.isTerm &&
1089-
(cls.owner.flagsUNSAFE.is(Case) || cls.owner.name == nme.DOLLAR_NEW)
1087+
cls.isAnonymousClass
1088+
&& cls.owner.isTerm
1089+
&& (cls.owner.flagsUNSAFE.isAllOf(EnumCase)
1090+
|| ((cls.owner.name eq nme.DOLLAR_NEW) && cls.owner.flagsUNSAFE.isAllOf(Private | Synthetic)))
10901091
if (!isEnumAnonCls)
10911092
if (cdef.mods.isEnumCase) {
10921093
if (cls.derivesFrom(defn.JavaEnumClass))
@@ -1101,8 +1102,10 @@ trait Checking {
11011102
report.error(ClassCannotExtendEnum(cls, firstParent), cdef.sourcePos)
11021103
}
11031104

1104-
/** Check that the firstParent derives from the declaring enum class, if not, adds it as a parent after emitting an
1105-
* error.
1105+
/** Check that the firstParent for an enum case derives from the declaring enum class, if not, adds it as a parent
1106+
* after emitting an error.
1107+
*
1108+
* This check will have no effect on simple enum cases as their parents are inferred by the compiler.
11061109
*/
11071110
def checkEnumParent(cls: Symbol, firstParent: Symbol)(using Context): Unit =
11081111

@@ -1119,8 +1122,8 @@ trait Checking {
11191122
case _ =>
11201123

11211124
val enumCase =
1122-
if cls.isAllOf(EnumCase) then cls
1123-
else if cls.isAnonymousClass && cls.owner.isAllOf(EnumCase) then cls.owner
1125+
if cls.flagsUNSAFE.isAllOf(EnumCase) then cls
1126+
else if cls.isAnonymousClass && cls.owner.flagsUNSAFE.isAllOf(EnumCase) then cls.owner
11241127
else NoSymbol
11251128
if enumCase.exists then
11261129
ensureParentDerivesFrom(enumCase)

tests/neg/enums.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ enum Option[+T] derives Eql {
4040
case None
4141
}
4242

43+
object DollarNew {
44+
45+
enum MyEnum:
46+
case A
47+
48+
object MyEnum:
49+
50+
def $new: MyEnum = new MyEnum with runtime.EnumValue { // error: anonymous class in method $new extends enum MyEnum, but extending enums is prohibited.
51+
override def $ordinal = 1
52+
}
53+
54+
final val F = $new
55+
}
56+
4357
object Test {
4458

4559
class Unrelated
@@ -48,4 +62,3 @@ object Test {
4862
x == new Unrelated // error: cannot compare
4963

5064
}
51-

0 commit comments

Comments
 (0)