@@ -168,22 +168,34 @@ object DesugarEnums {
168
168
}
169
169
}
170
170
171
- /** Is a type parameter in `tparams` referenced from an enum class case that has
172
- * given value parameters `vparamss` and given parents `parents`?
171
+ /** Is a type parameter in `enumTypeParams` referenced from an enum class case that has
172
+ * given type parameters `caseTypeParams`, value parameters `vparamss` and parents `parents`?
173
+ * Issues an error if that is the case but the reference is illegal.
174
+ * The reference could be illegal for two reasons:
175
+ * - explicit type parameters are given
176
+ * - it's a value case, i.e. no value parameters are given
173
177
*/
174
- def typeParamIsReferenced (tparams : List [TypeSymbol ], vparamss : List [List [ValDef ]], parents : List [Tree ])(implicit ctx : Context ): Boolean = {
178
+ def typeParamIsReferenced (
179
+ enumTypeParams : List [TypeSymbol ],
180
+ caseTypeParams : List [TypeDef ],
181
+ vparamss : List [List [ValDef ]],
182
+ parents : List [Tree ])(implicit ctx : Context ): Boolean = {
175
183
176
- val searchRef = new untpd. TreeAccumulator [Boolean ] {
177
- var tparamNames = tparams .map(_.name).toSet[Name ]
184
+ object searchRef extends UntypedTreeAccumulator [Boolean ] {
185
+ var tparamNames = enumTypeParams .map(_.name).toSet[Name ]
178
186
def underBinders (binders : List [MemberDef ], op : => Boolean ): Boolean = {
179
187
val saved = tparamNames
180
188
tparamNames = tparamNames -- binders.map(_.name)
181
189
try op
182
190
finally tparamNames = saved
183
191
}
184
- def apply (x : Boolean , tree : Tree )(implicit ctx : Context ) = x || {
192
+ def apply (x : Boolean , tree : Tree )(implicit ctx : Context ): Boolean = x || {
185
193
tree match {
186
- case Ident (name) => tparamNames.contains(name)
194
+ case Ident (name) =>
195
+ val matches = tparamNames.contains(name)
196
+ if (matches && (caseTypeParams.nonEmpty || vparamss.isEmpty))
197
+ ctx.error(i " illegal reference to type parameter $name from enum case " , tree.sourcePos)
198
+ matches
187
199
case LambdaTypeTree (lambdaParams, body) =>
188
200
underBinders(lambdaParams, foldOver(x, tree))
189
201
case RefinedTypeTree (parent, refinements) =>
@@ -192,9 +204,11 @@ object DesugarEnums {
192
204
case _ => foldOver(x, tree)
193
205
}
194
206
}
207
+ def apply (tree : Tree )(implicit ctx : Context ): Boolean =
208
+ underBinders(caseTypeParams, apply(false , tree))
195
209
}
196
210
197
- def typeHasRef (tpt : Tree ) = searchRef(false , tpt)
211
+ def typeHasRef (tpt : Tree ) = searchRef(tpt)
198
212
def valDefHasRef (vd : ValDef ) = typeHasRef(vd.tpt)
199
213
def parentHasRef (parent : Tree ): Boolean = parent match {
200
214
case Apply (fn, _) => parentHasRef(fn)
@@ -204,9 +218,7 @@ object DesugarEnums {
204
218
case parent => parent.isType && typeHasRef(parent)
205
219
}
206
220
207
- parents.isEmpty || // a parent class that refers to type parameters will be generated in this case
208
- vparamss.exists(_.exists(valDefHasRef)) ||
209
- parents.exists(parentHasRef)
221
+ vparamss.exists(_.exists(valDefHasRef)) || parents.exists(parentHasRef)
210
222
}
211
223
212
224
/** A pair consisting of
0 commit comments