@@ -104,22 +104,30 @@ object DesugarEnums {
104
104
105
105
/** The following lists of definitions for an enum type E and known value cases e_0, ..., e_n:
106
106
*
107
- * private val $values = Array[E](e_0,...,e_n)(ClassTag[E](classOf[E]))
107
+ * private val $values = Array[E](this. e_0,...,this. e_n)(ClassTag[E](classOf[E])): @unchecked
108
108
* def values = $values.clone
109
109
* def valueOf($name: String) = $name match {
110
- * case "e_0" => e_0
110
+ * case "e_0" => this. e_0
111
111
* ...
112
- * case "e_n" => e_n
112
+ * case "e_n" => this. e_n
113
113
* case _ => throw new IllegalArgumentException("case not found: " + $name)
114
114
* }
115
115
*/
116
116
private def enumScaffolding (enumValues : List [RefTree ])(using Context ): List [Tree ] = {
117
117
val rawEnumClassRef = rawRef(enumClass.typeRef)
118
118
extension (tpe : NamedType ) def ofRawEnum = AppliedTypeTree (ref(tpe), rawEnumClassRef)
119
119
120
- val lazyFlagOpt = if enumCompanion.owner.isStatic then EmptyFlags else Lazy
121
- val privateValuesDef = ValDef (nme.DOLLAR_VALUES , TypeTree (), ArrayLiteral (enumValues, rawEnumClassRef))
122
- .withFlags(Private | Synthetic | lazyFlagOpt)
120
+ val privateValuesDef =
121
+ val uncheckedValues =
122
+ // Here we use an unchecked annotation to silence warnings from the init checker. Without it, we get a warning
123
+ // that simple enum cases are promoting this from warm to initialised. This is because we are populating the
124
+ // array by selecting enum values from `this`, a value under construction.
125
+ // Singleton enum values always construct a new anonymous class, which will not be checked by the init-checker,
126
+ // so this warning will always persist even if the implementation of the anonymous class is safe.
127
+ // TODO: remove @unchecked after https://github.com/lampepfl/dotty-feature-requests/issues/135 is resolved.
128
+ Annotated (ArrayLiteral (enumValues, rawEnumClassRef), New (ref(defn.UncheckedAnnot .typeRef)))
129
+ ValDef (nme.DOLLAR_VALUES , TypeTree (), uncheckedValues)
130
+ .withFlags(Private | Synthetic )
123
131
124
132
val valuesDef =
125
133
DefDef (nme.values, Nil , Nil , defn.ArrayType .ofRawEnum, valuesDot(nme.clone_))
@@ -170,7 +178,6 @@ object DesugarEnums {
170
178
* def ordinal = _$ordinal // if `E` does not derive from `java.lang.Enum`
171
179
* def enumLabel = $name // if `E` does not derive from `java.lang.Enum`
172
180
* def enumLabel = this.name // if `E` derives from `java.lang.Enum`
173
- * $values.register(this)
174
181
* }
175
182
*/
176
183
private def enumValueCreator (using Context ) = {
@@ -307,8 +314,8 @@ object DesugarEnums {
307
314
case name : TermName => (ordinal, name) :: seenCases
308
315
case _ => seenCases
309
316
if definesLookups then
310
- val companionRef = ref(enumCompanion.termRef )
311
- val cachedValues = cases.reverse.map((i, name) => (i, Select (companionRef , name)))
317
+ val thisRef = This ( EmptyTypeIdent )
318
+ val cachedValues = cases.reverse.map((i, name) => (i, Select (thisRef , name)))
312
319
(ordinal, enumLookupMethods(EnumConstraints (minKind, maxKind, cachedValues)))
313
320
else
314
321
ctx.tree.pushAttachment(EnumCaseCount , (ordinal + 1 , minKind, maxKind, cases))
0 commit comments