Skip to content

Commit f0bbd95

Browse files
authored
Merge pull request #9942 from dotty-staging/topic/enum-rename-scala-enum
fix #9873: move scala.Enum to scala.reflect.Enum
2 parents ce88cae + 0591597 commit f0bbd95

File tree

22 files changed

+85
-108
lines changed

22 files changed

+85
-108
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)
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/semanticdb/ExtractSemanticDB.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import scala.jdk.CollectionConverters._
1717
import collection.mutable
1818
import java.nio.file.Paths
1919

20+
import dotty.tools.dotc.transform.SymUtils._
21+
2022
import PartialFunction.condOpt
2123

2224
import ast.untpd.{given _}
@@ -191,7 +193,7 @@ class ExtractSemanticDB extends Phase:
191193
val selfSpan = tree.self.span
192194
if selfSpan.exists && selfSpan.hasLength then
193195
traverse(tree.self)
194-
if tree.symbol.owner.is(Enum, butNot=Case) then
196+
if tree.symbol.owner.isEnumClass then
195197
tree.body.foreachUntilImport(traverse).foreach(traverse) // the first import statement
196198
else
197199
tree.body.foreach(traverse)

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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ trait Checking {
10731073
if !Inliner.inInlineMethod && !ctx.isInlineContext then
10741074
report.error(em"$what can only be used in an inline method", pos)
10751075

1076-
/** 1. Check that all case classes that extend `scala.Enum` are `enum` cases
1076+
/** 1. Check that all case classes that extend `scala.reflect.Enum` are `enum` cases
10771077
* 2. Check that parameterised `enum` cases do not extend java.lang.Enum.
10781078
* 3. Check that only a static `enum` base class can extend java.lang.Enum.
10791079
*/
@@ -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

docs/docs/reference/enums/enums.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,14 @@ For a more in-depth example of using Scala 3 enums from Java, see [this test](ht
109109

110110
### Implementation
111111

112-
Enums are represented as `sealed` classes that extend the `scala.Enum` trait.
112+
Enums are represented as `sealed` classes that extend the `scala.reflect.Enum` trait.
113113
This trait defines two public methods, `ordinal` and `enumLabel`:
114114

115115
```scala
116-
package scala
116+
package scala.reflect
117117

118-
/** A base trait of all enum classes */
119-
trait Enum extends Product with Serializable {
118+
/** A base trait of all Scala enum definitions */
119+
super trait Enum extends Any with Product with Serializable {
120120

121121
/** A string uniquely identifying a case of an enum */
122122
def enumLabel: String
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package scala
22

3-
/** 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
3+
/** A base trait of all Scala enum definitions */
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 Scala enum definitions */
4+
super trait Enum extends Any, 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

library/src-non-bootstrapped/scala/runtime/EnumValueSerializationProxy.java

Lines changed: 0 additions & 36 deletions
This file was deleted.

library/src-non-bootstrapped/scala/runtime/EnumValues.scala

Lines changed: 0 additions & 21 deletions
This file was deleted.

tastydoc/test/dotty/tastydoc/Tests.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ class Tests {
5555
//Individual files
5656
"scala.\\$times\\$colon*",
5757
"scala.Conversion*",
58-
"scala.Enum*",
5958
"scala.Eql*",
6059
"scala.forceInline*",
6160
"scala.FunctionXXL*",

tests/neg/enumsLabel-overrides.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
trait Mixin { def enumLabel: String = "mixin" }
2+
3+
enum Mixed extends Mixin {
4+
case B // error: overriding method enumLabel in trait Mixin of type => String;
5+
}
6+
7+
enum MixedAlso {
8+
case C extends MixedAlso with Mixin // error: overriding method enumLabel in trait Mixin of type => String;
9+
}
10+
11+
trait HasEnumLabel { def enumLabel: String }
12+
13+
enum MyEnum extends HasEnumLabel {
14+
case D // ok
15+
}

tests/neg/enumsLabel-singleimpl.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
enum Labelled {
2+
3+
case A // error: method enumLabel of type => String needs `override` modifier
4+
5+
def enumLabel: String = "nolabel"
6+
7+
}
8+
9+
enum Ordinalled {
10+
11+
case A // error: method ordinal of type => Int needs `override` modifier
12+
13+
def ordinal: Int = -1
14+
15+
}

tests/neg/enumsLabelDef.scala

Lines changed: 0 additions & 22 deletions
This file was deleted.

tests/neg/supertraits.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@ case object b
1111
val y = if ??? then a else b
1212
val y1: Product = y // error
1313
val y2: Serializable = y // error
14+
15+
enum Color {
16+
case Red, Green, Blue
17+
}
18+
19+
enum Nucleobase {
20+
case A, C, G, T
21+
}
22+
23+
val z = if ??? then Color.Red else Nucleobase.G
24+
val z1: reflect.Enum = z // error: Found: (z : Object) Required: reflect.Enum

tests/patmat/i7186.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import MIPS._
22

3+
import deriving.Mirror.SumOf
4+
35
object MIPS {
46
type Labels = Label | ControlLabel
57
type Src = Register | Constant
@@ -233,8 +235,8 @@ object printMips {
233235
def getScopedLabel(s: Scoped): String =
234236
"L" + getScopedId(s)
235237

236-
def printEnum[E](e: String => Enum, t: E, code: String) = {
237-
val num = e(t.toString).ordinal
238+
def printEnum[E: SumOf](e: String => E, t: E, code: String) = {
239+
val num = summon[SumOf[E]].ordinal(e(t.toString))
238240
s"$code$num"
239241
}
240242
}

tests/pos/enum-List-control.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
abstract sealed class List[T] extends Enum
1+
abstract sealed class List[T] extends reflect.Enum
22
object List {
33
final class Cons[T](x: T, xs: List[T]) extends List[T] {
44
def ordinal = 0

tests/run/generic/Enum.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ object runtime {
2222
}
2323
def values: Iterable[E] = myMap.values
2424
}
25-
}
25+
}

0 commit comments

Comments
 (0)