@@ -168,22 +168,34 @@ object DesugarEnums {
168168 }
169169 }
170170
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
173177 */
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 = {
175183
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 ]
178186 def underBinders (binders : List [MemberDef ], op : => Boolean ): Boolean = {
179187 val saved = tparamNames
180188 tparamNames = tparamNames -- binders.map(_.name)
181189 try op
182190 finally tparamNames = saved
183191 }
184- def apply (x : Boolean , tree : Tree )(implicit ctx : Context ) = x || {
192+ def apply (x : Boolean , tree : Tree )(implicit ctx : Context ): Boolean = x || {
185193 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
187199 case LambdaTypeTree (lambdaParams, body) =>
188200 underBinders(lambdaParams, foldOver(x, tree))
189201 case RefinedTypeTree (parent, refinements) =>
@@ -192,9 +204,11 @@ object DesugarEnums {
192204 case _ => foldOver(x, tree)
193205 }
194206 }
207+ def apply (tree : Tree )(implicit ctx : Context ): Boolean =
208+ underBinders(caseTypeParams, apply(false , tree))
195209 }
196210
197- def typeHasRef (tpt : Tree ) = searchRef(false , tpt)
211+ def typeHasRef (tpt : Tree ) = searchRef(tpt)
198212 def valDefHasRef (vd : ValDef ) = typeHasRef(vd.tpt)
199213 def parentHasRef (parent : Tree ): Boolean = parent match {
200214 case Apply (fn, _) => parentHasRef(fn)
@@ -204,9 +218,7 @@ object DesugarEnums {
204218 case parent => parent.isType && typeHasRef(parent)
205219 }
206220
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)
210222 }
211223
212224 /** A pair consisting of
0 commit comments