Skip to content

Commit 54f9ef5

Browse files
committed
fix scala#9873: move scala.Enum to scala.reflect.Enum
scala.reflect.Enum is now a universal super trait. Also avoid using derivesFrom(defn.EnumClass) and instead look for enum flag.
1 parent 4b8a1de commit 54f9ef5

File tree

19 files changed

+76
-100
lines changed

19 files changed

+76
-100
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ object desugar {
403403
val isCaseObject = mods.is(Case) && isObject
404404
val isEnum = mods.isEnumClass && !mods.is(Module)
405405
def isEnumCase = mods.isEnumCase
406+
def isNonEnumCase = !isEnumCase && (isCaseClass || isCaseObject)
406407
val isValueClass = parents.nonEmpty && isAnyVal(parents.head)
407408
// This is not watertight, but `extends AnyVal` will be replaced by `inline` later.
408409

@@ -621,10 +622,10 @@ object desugar {
621622
var parents1 = parents
622623
if (isEnumCase && parents.isEmpty)
623624
parents1 = enumClassTypeRef :: Nil
624-
if (isCaseClass | isCaseObject)
625+
if (isNonEnumCase && !isEnum)
625626
parents1 = parents1 :+ scalaDot(str.Product.toTypeName) :+ scalaDot(nme.Serializable.toTypeName)
626627
if (isEnum)
627-
parents1 = parents1 :+ ref(defn.EnumClass.typeRef)
628+
parents1 = parents1 :+ ref(defn.EnumClass)
628629

629630
// derived type classes of non-module classes go to their companions
630631
val (clsDerived, companionDerived) =

compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,10 @@ object DesugarEnums {
282282
private def isJavaEnum(using Context): Boolean = enumClass.derivesFrom(defn.JavaEnumClass)
283283

284284
def ordinalMeth(body: Tree)(using Context): DefDef =
285-
DefDef(nme.ordinal, Nil, Nil, TypeTree(defn.IntType), body)
285+
DefDef(nme.ordinal, Nil, Nil, TypeTree(defn.IntType), body).withAddedFlags(Synthetic)
286286

287287
def enumLabelMeth(body: Tree)(using Context): DefDef =
288-
DefDef(nme.enumLabel, Nil, Nil, TypeTree(defn.StringType), body)
288+
DefDef(nme.enumLabel, Nil, Nil, TypeTree(defn.StringType), body).withAddedFlags(Synthetic)
289289

290290
def ordinalMethLit(ord: Int)(using Context): DefDef =
291291
ordinalMeth(Literal(Constant(ord)))

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ class Definitions {
754754
@tu lazy val SomeClass: ClassSymbol = requiredClass("scala.Some")
755755
@tu lazy val NoneModule: Symbol = requiredModule("scala.None")
756756

757-
@tu lazy val EnumClass: ClassSymbol = requiredClass("scala.Enum")
757+
@tu lazy val EnumClass: ClassSymbol = requiredClass("scala.reflect.Enum")
758758

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

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ object SymUtils {
171171
self
172172
}
173173

174+
def isEnum(using Context): Boolean = self.is(Enum, butNot=JavaDefined)
175+
def isEnumClass(using Context): Boolean = isEnum && !self.is(Case)
176+
174177
/** Does this symbol refer to anonymous classes synthesized by enum desugaring? */
175178
def isEnumAnonymClass(using Context): Boolean =
176179
self.isAnonymousClass && (self.owner.name.eq(nme.DOLLAR_NEW) || self.owner.is(CaseVal))

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
9494
lazy val accessors =
9595
if (isDerivedValueClass(clazz)) clazz.paramAccessors.take(1) // Tail parameters can only be `erased`
9696
else clazz.caseAccessors
97-
val isEnumCase = clazz.derivesFrom(defn.EnumClass) && clazz != defn.EnumClass
98-
val isEnumValue = isEnumCase && clazz.isAnonymousClass && clazz.classParents.head.classSymbol.is(Enum)
97+
val isEnumValue = clazz.isAnonymousClass && clazz.classParents.head.classSymbol.is(Enum)
9998
val isNonJavaEnumValue = isEnumValue && !clazz.derivesFrom(defn.JavaEnumClass)
10099

101100
val symbolsToSynthesize: List[Symbol] =

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,7 @@ trait Checking {
10941094
// Since enums are classes and Namer checks that classes don't extend multiple classes, we only check the class
10951095
// parent.
10961096
//
1097-
// Unlike firstParent.derivesFrom(defn.EnumClass), this test allows inheriting from `Enum` by hand;
1097+
// this test allows inheriting from `Enum` by hand;
10981098
// see enum-List-control.scala.
10991099
report.error(ClassCannotExtendEnum(cls, firstParent), cdef.srcPos)
11001100
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,7 +2106,8 @@ class Typer extends Namer
21062106
val constr1 = typed(constr).asInstanceOf[DefDef]
21072107
val parentsWithClass = ensureFirstTreeIsClass(parents.mapconserve(typedParent).filterConserve(!_.isEmpty), cdef.nameSpan)
21082108
val parents1 = ensureConstrCall(cls, parentsWithClass)(using superCtx)
2109-
val firstParent = parents1.head.tpe.dealias.typeSymbol
2109+
val firstParentTpe = parents1.head.tpe.dealias
2110+
val firstParent = firstParentTpe.typeSymbol
21102111

21112112
checkEnumParent(cls, firstParent)
21122113

@@ -2123,7 +2124,7 @@ class Typer extends Namer
21232124
.withType(dummy.termRef)
21242125
if (!cls.isOneOf(AbstractOrTrait) && !ctx.isAfterTyper)
21252126
checkRealizableBounds(cls, cdef.sourcePos.withSpan(cdef.nameSpan))
2126-
if cls.derivesFrom(defn.EnumClass) then
2127+
if cls.isEnum || firstParentTpe.classSymbol.isEnum then
21272128
checkEnum(cdef, cls, firstParent)
21282129
val cdef1 = assignType(cpy.TypeDef(cdef)(name, impl1), cls)
21292130

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package scala
22

33
/** A base trait of all enum classes */
4-
trait Enum extends Product, Serializable:
5-
6-
/** A string uniquely identifying a case of an enum */
7-
def enumLabel: String
8-
9-
/** A number uniquely identifying a case of an enum */
10-
def ordinal: Int
4+
@deprecated("scala.Enum has moved to scala.reflect.Enum", "3.0.0-M1")
5+
type Enum = scala.reflect.Enum
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package scala.reflect
2+
3+
/** A base trait of all enum classes */
4+
super trait Enum extends Any with Product, Serializable:
5+
6+
/** A string uniquely identifying a case of an enum */
7+
def enumLabel: String
8+
9+
/** A number uniquely identifying a case of an enum */
10+
def ordinal: Int

library/src-non-bootstrapped/scala/Enum.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@ package scala
33
/** A base trait of all enum classes */
44
trait Enum extends Product, Serializable:
55

6+
/** A string uniquely identifying a case of an enum */
7+
def enumLabel: String
8+
69
/** A number uniquely identifying a case of an enum */
710
def ordinal: Int

0 commit comments

Comments
 (0)