@@ -310,6 +310,34 @@ class TypeApplications(val self: Type) extends AnyVal {
310310 def ensureLambdaSub (using Context ): Type =
311311 if (isLambdaSub) self else EtaExpansion (self)
312312
313+
314+ /** Convert a type constructor `TC` which has type parameters `X1, ..., Xn`
315+ * to `[X1, ..., Xn] -> TC[X1, ..., Xn]`.
316+ */
317+ def etaExpand (using Context ): Type =
318+ val tparams = self.typeParams
319+ val resType = self.appliedTo(tparams.map(_.paramRef))
320+ self.dealias match
321+ case self : TypeRef if tparams.nonEmpty && self.symbol.isClass =>
322+ val owner = self.symbol.owner
323+ // Calling asSeenFrom on the type parameter infos is important
324+ // so that class type references within another prefix have
325+ // their type parameters' info fixed.
326+ // e.g. from pos/i18569:
327+ // trait M1:
328+ // trait A
329+ // trait F[T <: A]
330+ // object M2 extends M1
331+ // Type parameter T in M1.F has an upper bound of M1#A
332+ // But eta-expanding M2.F should have type parameters with an upper-bound of M2.A.
333+ // So we take the prefix M2.type and the F symbol's owner, M1,
334+ // to call asSeenFrom on T's info.
335+ HKTypeLambda (tparams.map(_.paramName))(
336+ tl => tparams.map(p => HKTypeLambda .toPInfo(tl.integrate(tparams, p.paramInfo.asSeenFrom(self.prefix, owner)))),
337+ tl => tl.integrate(tparams, resType))
338+ case _ =>
339+ HKTypeLambda .fromParams(tparams, resType)
340+
313341 /** Eta expand if `self` is a (non-lambda) class reference and `bound` is a higher-kinded type */
314342 def EtaExpandIfHK (bound : Type )(using Context ): Type = {
315343 val hkParams = bound.hkTypeParams
0 commit comments