diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 6c07cc1a7a4d..f802edbd9a98 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -586,7 +586,9 @@ object desugar { yield syntheticProperty(selName, caseParams(i).tpt, Select(This(EmptyTypeIdent), caseParams(i).name)) - def ordinalMeths = if (isEnumCase) ordinalMethLit(nextOrdinal(CaseKind.Class)._1) :: Nil else Nil + def enumMeths = + if (isEnumCase) ordinalMethLit(nextOrdinal(CaseKind.Class)._1) :: enumLabelLit(className.toString) :: Nil + else Nil def copyMeths = { val hasRepeatedParam = constrVparamss.exists(_.exists { case ValDef(_, tpt, _) => isRepeated(tpt) @@ -605,7 +607,7 @@ object desugar { } if (isCaseClass) - copyMeths ::: ordinalMeths ::: productElemMeths + copyMeths ::: enumMeths ::: productElemMeths else Nil } diff --git a/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala b/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala index d029b686e138..fc9c843f0e3e 100644 --- a/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala +++ b/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala @@ -125,18 +125,21 @@ object DesugarEnums { /** A creation method for a value of enum type `E`, which is defined as follows: * * private def $new(_$ordinal: Int, $name: String) = new E with scala.runtime.EnumValue { - * def ordinal = _$ordinal // if `E` does not derive from jl.Enum - * override def toString = $name // if `E` does not derive from jl.Enum + * def ordinal = _$ordinal // if `E` does not derive from `java.lang.Enum` + * def enumLabel = $name // if `E` does not derive from `java.lang.Enum` + * def enumLabel = this.name // if `E` derives from `java.lang.Enum` * $values.register(this) * } */ private def enumValueCreator(using Context) = { val fieldMethods = - if isJavaEnum then Nil - else - val ordinalDef = ordinalMeth(Ident(nme.ordinalDollar_)) - val toStringDef = toStringMeth(Ident(nme.nameDollar)) - List(ordinalDef, toStringDef) + if isJavaEnum then + val enumLabelDef = enumLabelMeth(Select(This(Ident(tpnme.EMPTY)), nme.name)) + enumLabelDef :: Nil + else + val ordinalDef = ordinalMeth(Ident(nme.ordinalDollar_)) + val enumLabelDef = enumLabelMeth(Ident(nme.nameDollar)) + ordinalDef :: enumLabelDef :: Nil val creator = New(Template( constr = emptyConstructor, parents = enumClassRef :: scalaRuntimeDot(tpnme.EnumValue) :: Nil, @@ -273,14 +276,14 @@ object DesugarEnums { def ordinalMeth(body: Tree)(using Context): DefDef = DefDef(nme.ordinal, Nil, Nil, TypeTree(defn.IntType), body) - def toStringMeth(body: Tree)(using Context): DefDef = - DefDef(nme.toString_, Nil, Nil, TypeTree(defn.StringType), body).withFlags(Override) + def enumLabelMeth(body: Tree)(using Context): DefDef = + DefDef(nme.enumLabel, Nil, Nil, TypeTree(defn.StringType), body) def ordinalMethLit(ord: Int)(using Context): DefDef = ordinalMeth(Literal(Constant(ord))) - def toStringMethLit(name: String)(using Context): DefDef = - toStringMeth(Literal(Constant(name))) + def enumLabelLit(name: String)(using Context): DefDef = + enumLabelMeth(Literal(Constant(name))) /** Expand a module definition representing a parameterless enum case */ def expandEnumModule(name: TermName, impl: Template, mods: Modifiers, span: Span)(using Context): Tree = { @@ -290,16 +293,12 @@ object DesugarEnums { expandSimpleEnumCase(name, mods, span) else { val (tag, scaffolding) = nextOrdinal(CaseKind.Object) - val fieldMethods = - if isJavaEnum then Nil - else - val ordinalDef = ordinalMethLit(tag) - val toStringDef = toStringMethLit(name.toString) - List(ordinalDef, toStringDef) + val ordinalDef = if isJavaEnum then Nil else ordinalMethLit(tag) :: Nil + val enumLabelDef = enumLabelLit(name.toString) val impl1 = cpy.Template(impl)( parents = impl.parents :+ scalaRuntimeDot(tpnme.EnumValue), - body = fieldMethods ::: registerCall :: Nil) - .withAttachment(ExtendsSingletonMirror, ()) + body = ordinalDef ::: enumLabelDef :: registerCall :: Nil + ).withAttachment(ExtendsSingletonMirror, ()) val vdef = ValDef(name, TypeTree(), New(impl1)).withMods(mods.withAddedFlags(EnumValue, span)) flatTree(scaffolding ::: vdef :: Nil).withSpan(span) } diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 418d7f3027c9..55dd7464e789 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -648,7 +648,6 @@ class Definitions { @tu lazy val NoneModule: Symbol = requiredModule("scala.None") @tu lazy val EnumClass: ClassSymbol = requiredClass("scala.Enum") - @tu lazy val Enum_ordinal: Symbol = EnumClass.requiredMethod(nme.ordinal) @tu lazy val EnumValuesClass: ClassSymbol = requiredClass("scala.runtime.EnumValues") diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 8156a310e2a4..5ec7fe75aca5 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -453,6 +453,7 @@ object StdNames { val emptyValDef: N = "emptyValDef" val end: N = "end" val ensureAccessible : N = "ensureAccessible" + val enumLabel: N = "enumLabel" val eq: N = "eq" val eqInstance: N = "eqInstance" val equalsNumChar : N = "equalsNumChar" diff --git a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala index 37f0128d5520..44d43922f946 100644 --- a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala +++ b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala @@ -57,6 +57,8 @@ class SyntheticMembers(thisPhase: DenotTransformer) { private var myValueSymbols: List[Symbol] = Nil private var myCaseSymbols: List[Symbol] = Nil private var myCaseModuleSymbols: List[Symbol] = Nil + private var myEnumValueSymbols: List[Symbol] = Nil + private var myNonJavaEnumValueSymbols: List[Symbol] = Nil private def initSymbols(using Context) = if (myValueSymbols.isEmpty) { @@ -65,11 +67,15 @@ class SyntheticMembers(thisPhase: DenotTransformer) { defn.Product_productArity, defn.Product_productPrefix, defn.Product_productElement, defn.Product_productElementName) myCaseModuleSymbols = myCaseSymbols.filter(_ ne defn.Any_equals) + myEnumValueSymbols = List(defn.Product_productPrefix) + myNonJavaEnumValueSymbols = myEnumValueSymbols :+ defn.Any_toString } def valueSymbols(using Context): List[Symbol] = { initSymbols; myValueSymbols } def caseSymbols(using Context): List[Symbol] = { initSymbols; myCaseSymbols } def caseModuleSymbols(using Context): List[Symbol] = { initSymbols; myCaseModuleSymbols } + def enumValueSymbols(using Context): List[Symbol] = { initSymbols; myEnumValueSymbols } + def nonJavaEnumValueSymbols(using Context): List[Symbol] = { initSymbols; myNonJavaEnumValueSymbols } private def existingDef(sym: Symbol, clazz: ClassSymbol)(using Context): Symbol = { val existing = sym.matchingMember(clazz.thisType) @@ -89,11 +95,15 @@ class SyntheticMembers(thisPhase: DenotTransformer) { if (isDerivedValueClass(clazz)) clazz.paramAccessors.take(1) // Tail parameters can only be `erased` else clazz.caseAccessors val isEnumCase = clazz.derivesFrom(defn.EnumClass) && clazz != defn.EnumClass + val isEnumValue = isEnumCase && clazz.isAnonymousClass && clazz.classParents.head.classSymbol.is(Enum) + val isNonJavaEnumValue = isEnumValue && !clazz.derivesFrom(defn.JavaEnumClass) val symbolsToSynthesize: List[Symbol] = if (clazz.is(Case)) if (clazz.is(Module)) caseModuleSymbols else caseSymbols + else if (isNonJavaEnumValue) nonJavaEnumValueSymbols + else if (isEnumValue) enumValueSymbols else if (isDerivedValueClass(clazz)) valueSymbols else Nil @@ -113,13 +123,22 @@ class SyntheticMembers(thisPhase: DenotTransformer) { def ownName: Tree = Literal(Constant(clazz.name.stripModuleClassSuffix.toString)) + def callEnumLabel: Tree = + Select(This(clazz), nme.enumLabel).ensureApplied + + def toStringBody(vrefss: List[List[Tree]]): Tree = + if (clazz.is(ModuleClass)) ownName + else if (isNonJavaEnumValue) callEnumLabel + else forwardToRuntime(vrefss.head) + def syntheticRHS(vrefss: List[List[Tree]])(using Context): Tree = synthetic.name match { case nme.hashCode_ if isDerivedValueClass(clazz) => valueHashCodeBody case nme.hashCode_ => chooseHashcode - case nme.toString_ => if (clazz.is(ModuleClass)) ownName else forwardToRuntime(vrefss.head) + case nme.toString_ => toStringBody(vrefss) case nme.equals_ => equalsBody(vrefss.head.head) case nme.canEqual_ => canEqualBody(vrefss.head.head) case nme.productArity => Literal(Constant(accessors.length)) + case nme.productPrefix if isEnumValue => callEnumLabel case nme.productPrefix => ownName case nme.productElement => productElementBody(accessors.length, vrefss.head.head) case nme.productElementName => productElementNameBody(accessors.length, vrefss.head.head) diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index b8f3a1da13dd..2b8987103556 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1130,6 +1130,7 @@ trait Checking { end checkEnumParent + /** Check that all references coming from enum cases in an enum companion object * are legal. * @param cdef the enum companion object class diff --git a/docs/docs/reference/enums/desugarEnums.md b/docs/docs/reference/enums/desugarEnums.md index b9bf2995ffed..3ce196f6dc33 100644 --- a/docs/docs/reference/enums/desugarEnums.md +++ b/docs/docs/reference/enums/desugarEnums.md @@ -174,15 +174,19 @@ If `E` contains at least one simple case, its companion object will define in ad follows. ```scala private def $new(_$ordinal: Int, $name: String) = new E with runtime.EnumValue { - def ordinal = _$ordinal // if `E` does not have `java.lang.Enum` as a parent - override def toString = $name // if `E` does not have `java.lang.Enum` as a parent + def ordinal = _$ordinal + def enumLabel = $name + override def productPrefix = enumLabel // if not overridden in `E` + override def toString = enumLabel // if not overridden in `E` $values.register(this) // register enum value so that `valueOf` and `values` can return it. } ``` The anonymous class also implements the abstract `Product` methods that it inherits from `Enum`. -The `ordinal` method is only generated if the enum does not extend from `java.lang.Enum` (as Scala enums do not extend `java.lang.Enum`s unless explicitly specified). In case it does, there is no need to generate `ordinal` as `java.lang.Enum` defines it. Similarly there is no need to override `toString` as that is defined in terms of `name` in -`java.lang.Enum`. +The `ordinal` method is only generated if the enum does not extend from `java.lang.Enum` (as Scala enums do not extend +`java.lang.Enum`s unless explicitly specified). In case it does, there is no need to generate `ordinal` as +`java.lang.Enum` defines it. Similarly there is no need to override `toString` as that is defined in terms of `name` in +`java.lang.Enum`. Finally, `enumLabel` will call `this.name` when `E` extends `java.lang.Enum`. ### Scopes for Enum Cases diff --git a/docs/docs/reference/enums/enums.md b/docs/docs/reference/enums/enums.md index 90e52bdb2414..37af6760b224 100644 --- a/docs/docs/reference/enums/enums.md +++ b/docs/docs/reference/enums/enums.md @@ -110,7 +110,7 @@ For a more in-depth example of using Scala 3 enums from Java, see [this test](ht ### Implementation Enums are represented as `sealed` classes that extend the `scala.Enum` trait. -This trait defines a single public method, `ordinal`: +This trait defines two public methods, `ordinal` and `enumLabel`: ```scala package scala @@ -118,6 +118,9 @@ package scala /** A base trait of all enum classes */ trait Enum extends Product with Serializable { + /** A string uniquely identifying a case of an enum */ + def enumLabel: String + /** A number uniquely identifying a case of an enum */ def ordinal: Int } @@ -130,7 +133,9 @@ For instance, the `Venus` value above would be defined like this: val Venus: Planet = new Planet(4.869E24, 6051800.0) { def ordinal: Int = 1 - override def toString: String = "Venus" + def enumLabel: String = "Venus" + override def productPrefix: String = enumLabel + override def toString: String = enumLabel // internal code to register value } ``` diff --git a/library/src-bootstrapped/scala/Enum.scala b/library/src-bootstrapped/scala/Enum.scala index ce21eb12cd08..ff713f90fe11 100644 --- a/library/src-bootstrapped/scala/Enum.scala +++ b/library/src-bootstrapped/scala/Enum.scala @@ -3,5 +3,8 @@ package scala /** A base trait of all enum classes */ trait Enum extends Product, Serializable: + /** A string uniquely identifying a case of an enum */ + def enumLabel: String + /** A number uniquely identifying a case of an enum */ def ordinal: Int diff --git a/library/src-bootstrapped/scala/runtime/EnumValues.scala b/library/src-bootstrapped/scala/runtime/EnumValues.scala new file mode 100644 index 000000000000..c34f5cd974c0 --- /dev/null +++ b/library/src-bootstrapped/scala/runtime/EnumValues.scala @@ -0,0 +1,21 @@ +package scala.runtime + +import scala.collection.immutable.TreeMap + +class EnumValues[E <: Enum] { + private[this] var myMap: Map[Int, E] = TreeMap.empty + private[this] var fromNameCache: Map[String, E] = null + + def register(v: E) = { + require(!myMap.contains(v.ordinal)) + myMap = myMap.updated(v.ordinal, v) + fromNameCache = null + } + + def fromInt: Map[Int, E] = myMap + def fromName: Map[String, E] = { + if (fromNameCache == null) fromNameCache = myMap.values.map(v => v.enumLabel -> v).toMap + fromNameCache + } + def values: Iterable[E] = myMap.values +} diff --git a/library/src/scala/runtime/EnumValues.scala b/library/src-non-bootstrapped/scala/runtime/EnumValues.scala similarity index 100% rename from library/src/scala/runtime/EnumValues.scala rename to library/src-non-bootstrapped/scala/runtime/EnumValues.scala diff --git a/library/src/scala/runtime/EnumValue.scala b/library/src/scala/runtime/EnumValue.scala index 8b1fa88a1076..55eaf7d48d1a 100644 --- a/library/src/scala/runtime/EnumValue.scala +++ b/library/src/scala/runtime/EnumValue.scala @@ -3,7 +3,6 @@ package scala.runtime super trait EnumValue extends Product, Serializable: override def canEqual(that: Any) = this eq that.asInstanceOf[AnyRef] override def productArity: Int = 0 - override def productPrefix: String = toString override def productElement(n: Int): Any = throw IndexOutOfBoundsException(n.toString) override def productElementName(n: Int): String = diff --git a/tests/neg/enumsLabelDef.scala b/tests/neg/enumsLabelDef.scala new file mode 100644 index 000000000000..99ecffc73df1 --- /dev/null +++ b/tests/neg/enumsLabelDef.scala @@ -0,0 +1,19 @@ +enum Labelled { + + case A // error overriding method enumLabel in class Labelled of type => String; + case B(arg: Int) // error overriding method enumLabel in class Labelled of type => String; + + def enumLabel: String = "nolabel" +} + +trait Mixin { def enumLabel: String = "mixin" } + +enum Mixed extends Mixin { + case C // error overriding method enumLabel in trait Mixin of type => String; +} + +trait HasEnumLabel { def enumLabel: String } + +enum MyEnum extends HasEnumLabel { + case D // ok +} diff --git a/tests/pos/enum-List-control.scala b/tests/pos/enum-List-control.scala index b52c9b41ec87..8fce310eb141 100644 --- a/tests/pos/enum-List-control.scala +++ b/tests/pos/enum-List-control.scala @@ -2,6 +2,7 @@ abstract sealed class List[T] extends Enum object List { final class Cons[T](x: T, xs: List[T]) extends List[T] { def ordinal = 0 + def enumLabel = "Cons" def canEqual(that: Any): Boolean = that.isInstanceOf[Cons[_]] def productArity: Int = 2 def productElement(n: Int): Any = n match @@ -13,6 +14,7 @@ object List { } final class Nil[T]() extends List[T], runtime.EnumValue { def ordinal = 1 + def enumLabel = "Nil" } object Nil { def apply[T](): List[T] = new Nil() diff --git a/tests/run/enum-custom-toString.scala b/tests/run/enum-custom-toString.scala new file mode 100644 index 000000000000..4c2007fbfe1c --- /dev/null +++ b/tests/run/enum-custom-toString.scala @@ -0,0 +1,92 @@ +enum ES: + case A + override def toString: String = "overridden" + +enum EJ extends java.lang.Enum[EJ]: + case B + override def toString: String = "overridden" + +trait Mixin extends Enum: + override def productPrefix: String = "noprefix" + override def toString: String = "overridden" + +enum EM extends Mixin: + case C + +enum ET[T] extends java.lang.Enum[ET[_]]: + case D extends ET[Unit] + override def toString: String = "overridden" + +enum EZ: + case E(arg: Int) + override def toString: String = "overridden" + +enum EC: // control case + case F + case G(arg: Int) + +enum EO: + case H + case I(arg: Int) + override def productPrefix: String = "noprefix" + override def toString: String = "overridden" +end EO + +enum EQ: + case J extends EQ with Mixin + case K(arg: Int) extends EQ with Mixin + +abstract class Tag[T] extends Enum +object Tag: + private final class IntTagImpl extends Tag[Int] with runtime.EnumValue: + def ordinal = 0 + def enumLabel = "IntTag" + override def hashCode = 123 + final val IntTag: Tag[Int] = IntTagImpl() + +@main def Test = + assert(ES.A.toString == "overridden", s"ES.A.toString = ${ES.A.toString}") + assert(ES.A.productPrefix == "A", s"ES.A.productPrefix = ${ES.A.productPrefix}") + assert(ES.A.enumLabel == "A", s"ES.A.enumLabel = ${ES.A.enumLabel}") + assert(ES.valueOf("A") == ES.A, s"ES.valueOf(A) = ${ES.valueOf("A")}") + assert(EJ.B.toString == "overridden", s"EJ.B.toString = ${EJ.B.toString}") + assert(EJ.B.productPrefix == "B", s"EJ.B.productPrefix = ${EJ.B.productPrefix}") + assert(EJ.B.enumLabel == "B", s"EJ.B.enumLabel = ${EJ.B.enumLabel}") + assert(EJ.valueOf("B") == EJ.B, s"EJ.valueOf(B) = ${EJ.valueOf("B")}") + assert(EM.C.toString == "overridden", s"EM.C.toString = ${EM.C.toString}") + assert(EM.C.productPrefix == "noprefix", s"EM.C.productPrefix = ${EM.C.productPrefix}") + assert(EM.C.enumLabel == "C", s"EM.C.enumLabel = ${EM.C.enumLabel}") + assert(EM.valueOf("C") == EM.C, s"EM.valueOf(C) = ${EM.valueOf("C")}") + assert(ET.D.toString == "overridden", s"ET.D.toString = ${ET.D.toString}") + assert(ET.D.productPrefix == "D", s"ET.D.productPrefix = ${ET.D.productPrefix}") + assert(ET.D.enumLabel == "D", s"ET.D.enumLabel = ${ET.D.enumLabel}") + assert(EZ.E(0).toString == "overridden", s"EZ.E(0).toString = ${EZ.E(0).toString}") + assert(EZ.E(0).productPrefix == "E", s"EZ.E(0).productPrefix = ${EZ.E(0).productPrefix}") + assert(EZ.E(0).enumLabel == "E", s"EZ.E(0).enumLabel = ${EZ.E(0).enumLabel}") + assert(EC.F.toString == "F", s"EC.F.toString = ${EC.F.toString}") + assert(EC.F.productPrefix == "F", s"EC.F.productPrefix = ${EC.F.productPrefix}") + assert(EC.F.enumLabel == "F", s"EC.F.enumLabel = ${EC.F.enumLabel}") + assert(EC.valueOf("F") == EC.F, s"EC.valueOf(F) = ${EC.valueOf("F")}") + assert(EC.G(0).toString == "G(0)", s"EC.G(0).toString = ${EC.G(0).toString}") + assert(EC.G(0).productPrefix == "G", s"EC.G(0).productPrefix = ${EC.G(0).productPrefix}") + assert(EC.G(0).enumLabel == "G", s"EC.G(0).enumLabel = ${EC.G(0).enumLabel}") + assert(EO.H.toString == "overridden", s"EO.H.toString = ${EO.H.toString}") + assert(EO.H.productPrefix == "noprefix", s"EO.H.productPrefix = ${EO.H.productPrefix}") + assert(EO.H.enumLabel == "H", s"EO.H.enumLabel = ${EO.H.enumLabel}") + assert(EO.valueOf("H") == EO.H, s"EO.valueOf(H) = ${EO.valueOf("H")}") + assert(EO.I(0).toString == "overridden", s"EO.I(0).toString = ${EO.I(0).toString}") + assert(EO.I(0).productPrefix == "noprefix", s"EO.I(0).productPrefix = ${EO.I(0).productPrefix}") + assert(EO.I(0).enumLabel == "I", s"EO.I(0).enumLabel = ${EO.I(0).enumLabel}") + assert(EQ.J.toString == "overridden", s"EQ.J.toString = ${EQ.J.toString}") + assert(EQ.J.productPrefix == "noprefix", s"EQ.J.productPrefix = ${EQ.J.productPrefix}") + assert(EQ.J.enumLabel == "J", s"EQ.J.enumLabel = ${EQ.J.enumLabel}") + assert(EQ.valueOf("J") == EQ.J, s"EQ.valueOf(J) = ${EQ.valueOf("J")}") + assert(EQ.K(0).toString == "overridden", s"EQ.K(0).toString = ${EQ.K(0).toString}") + assert(EQ.K(0).productPrefix == "noprefix", s"EQ.K(0).productPrefix = ${EQ.K(0).productPrefix}") + assert(EQ.K(0).enumLabel == "K", s"EQ.K(0).enumLabel = ${EQ.K(0).enumLabel}") + assert(Tag.IntTag.productPrefix == "", s"Tag.IntTag.productPrefix = ${Tag.IntTag.productPrefix}") + assert(Tag.IntTag.enumLabel == "IntTag", s"Tag.IntTag.enumLabel = ${Tag.IntTag.enumLabel}") + assert( + assertion = Tag.IntTag.toString == s"${Tag.IntTag.getClass.getName}@${Integer.toHexString(123)}", + message = s"Tag.IntTag.toString = ${Tag.IntTag.toString}" + ) diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 89d15e15ed8d..b4f3651fd697 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -638,7 +638,7 @@ Schema => SemanticDB v4 Uri => Enums.scala Text => empty Language => Scala -Symbols => 165 entries +Symbols => 167 entries Occurrences => 203 entries Symbols: @@ -699,6 +699,7 @@ _empty_/Enums.Maybe.Just#copy$default$1().[A] => typeparam A _empty_/Enums.Maybe.Just#copy(). => method copy _empty_/Enums.Maybe.Just#copy().(value) => param value _empty_/Enums.Maybe.Just#copy().[A] => typeparam A +_empty_/Enums.Maybe.Just#enumLabel(). => method enumLabel _empty_/Enums.Maybe.Just#ordinal(). => method ordinal _empty_/Enums.Maybe.Just#value. => val method value _empty_/Enums.Maybe.Just. => final object Just @@ -791,6 +792,7 @@ _empty_/Enums.`<:<`.Refl#[C] => typeparam C _empty_/Enums.`<:<`.Refl#``(). => primary ctor _empty_/Enums.`<:<`.Refl#copy(). => method copy _empty_/Enums.`<:<`.Refl#copy().[C] => typeparam C +_empty_/Enums.`<:<`.Refl#enumLabel(). => method enumLabel _empty_/Enums.`<:<`.Refl#ordinal(). => method ordinal _empty_/Enums.`<:<`.Refl. => final object Refl _empty_/Enums.`<:<`.Refl.apply(). => method apply