@@ -310,6 +310,34 @@ class TypeApplications(val self: Type) extends AnyVal {
310
310
def ensureLambdaSub (using Context ): Type =
311
311
if (isLambdaSub) self else EtaExpansion (self)
312
312
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
+
313
341
/** Eta expand if `self` is a (non-lambda) class reference and `bound` is a higher-kinded type */
314
342
def EtaExpandIfHK (bound : Type )(using Context ): Type = {
315
343
val hkParams = bound.hkTypeParams
0 commit comments