@@ -168,6 +168,47 @@ 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`?
173+ */
174+ def typeParamIsReferenced (tparams : List [TypeSymbol ], vparamss : List [List [ValDef ]], parents : List [Tree ])(implicit ctx : Context ): Boolean = {
175+
176+ val searchRef = new untpd.TreeAccumulator [Boolean ] {
177+ var tparamNames = tparams.map(_.name).toSet[Name ]
178+ def underBinders (binders : List [MemberDef ], op : => Boolean ): Boolean = {
179+ val saved = tparamNames
180+ tparamNames = tparamNames -- binders.map(_.name)
181+ try op
182+ finally tparamNames = saved
183+ }
184+ def apply (x : Boolean , tree : Tree )(implicit ctx : Context ) = x || {
185+ tree match {
186+ case Ident (name) => tparamNames.contains(name)
187+ case LambdaTypeTree (lambdaParams, body) =>
188+ underBinders(lambdaParams, foldOver(x, tree))
189+ case RefinedTypeTree (parent, refinements) =>
190+ val refinementDefs = refinements collect { case r : MemberDef => r }
191+ underBinders(refinementDefs, foldOver(x, tree))
192+ case _ => foldOver(x, tree)
193+ }
194+ }
195+ }
196+
197+ def typeHasRef (tpt : Tree ) = searchRef(false , tpt)
198+ def valDefHasRef (vd : ValDef ) = typeHasRef(vd.tpt)
199+ def parentHasRef (parent : Tree ): Boolean = parent match {
200+ case Apply (fn, _) => parentHasRef(fn)
201+ case TypeApply (_, targs) => targs.exists(typeHasRef)
202+ case Select (nu, nme.CONSTRUCTOR ) => parentHasRef(nu)
203+ case New (tpt) => typeHasRef(tpt)
204+ case parent if parent.isType => typeHasRef(parent)
205+ }
206+
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)
210+ }
211+
171212 /** A pair consisting of
172213 * - the next enum tag
173214 * - scaffolding containing the necessary definitions for singleton enum cases
0 commit comments