@@ -34,10 +34,6 @@ object TypeApplications {
34
34
*/
35
35
object EtaExpansion :
36
36
37
- def apply (tycon : Type )(using Context ): Type =
38
- assert(tycon.typeParams.nonEmpty, tycon)
39
- tycon.etaExpand(tycon.typeParamSymbols)
40
-
41
37
/** Test that the parameter bounds in a hk type lambda `[X1,...,Xn] => C[X1, ..., Xn]`
42
38
* contain the bounds of the type parameters of `C`. This is necessary to be able to
43
39
* contract the hk lambda to `C`.
@@ -245,7 +241,7 @@ class TypeApplications(val self: Type) extends AnyVal {
245
241
def topType (using Context ): Type =
246
242
if self.hasSimpleKind then
247
243
defn.AnyType
248
- else etaExpand( self.typeParams) match
244
+ else self.etaExpand match
249
245
case tp : HKTypeLambda =>
250
246
tp.derivedLambdaType(resType = tp.resultType.topType)
251
247
case _ =>
@@ -302,45 +298,49 @@ class TypeApplications(val self: Type) extends AnyVal {
302
298
/** Convert a type constructor `TC` which has type parameters `X1, ..., Xn`
303
299
* to `[X1, ..., Xn] -> TC[X1, ..., Xn]`.
304
300
*/
305
- def etaExpand (tparams : List [TypeParamInfo ])(using Context ): Type =
306
- HKTypeLambda .fromParams(tparams, self.appliedTo(tparams.map(_.paramRef)))
307
- // .ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
301
+ def etaExpand (using Context ): Type =
302
+ val tparams = self.typeParams
303
+ val resType = self.appliedTo(tparams.map(_.paramRef))
304
+ self match
305
+ case self : TypeRef if tparams.nonEmpty && self.symbol.isClass =>
306
+ val prefix = self.prefix
307
+ val owner = self.symbol.owner
308
+ // Calling asSeenFrom on the type parameter infos is important
309
+ // so that class type references within another prefix have
310
+ // their type parameters' info fixed.
311
+ // e.g. from pos/i18569:
312
+ // trait M1:
313
+ // trait A
314
+ // trait F[T <: A]
315
+ // object M2 extends M1
316
+ // Type parameter T in M1.F has an upper bound of M1#A
317
+ // But eta-expanding M2.F should have type parameters with an upper-bound of M2.A.
318
+ // So we take the prefix M2.type and the F symbol's owner, M1,
319
+ // to call asSeenFrom on T's info.
320
+ HKTypeLambda (tparams.map(_.paramName))(
321
+ tl => tparams.map(p => HKTypeLambda .toPInfo(tl.integrate(tparams, p.paramInfo.asSeenFrom(prefix, owner)))),
322
+ tl => tl.integrate(tparams, resType))
323
+ case _ =>
324
+ HKTypeLambda .fromParams(tparams, resType)
308
325
309
326
/** If self is not lambda-bound, eta expand it. */
310
327
def ensureLambdaSub (using Context ): Type =
311
- if (isLambdaSub) self else EtaExpansion (self)
328
+ if isLambdaSub then self
329
+ else
330
+ assert(self.typeParams.nonEmpty, self)
331
+ self.etaExpand
312
332
313
333
/** Eta expand if `self` is a (non-lambda) class reference and `bound` is a higher-kinded type */
314
334
def etaExpandIfHK (bound : Type )(using Context ): Type = {
315
335
val hkParams = bound.hkTypeParams
316
336
if (hkParams.isEmpty) self
317
337
else self match {
318
- case self : TypeRef if self.symbol.isClass && self.typeParams.length == hkParams.length =>
319
- EtaExpansion (self)
338
+ case self : TypeRef if self.symbol.isClass && self.typeParams.hasSameLengthAs( hkParams) =>
339
+ etaExpand
320
340
case _ => self
321
341
}
322
342
}
323
343
324
- // Like `target.etaExpand(target.typeParams)`
325
- // except call `asSeenFrom` to fix class type parameter bounds
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 M2.F has an upper bound of M1#A instead of M2.A
332
- // So we take the prefix M2.type and the F symbol's owner, M1,
333
- // to call asSeenFrom on T's info.
334
- def etaExpandWithAsf (using Context ): Type = self match
335
- case self : TypeRef if self.symbol.isClass =>
336
- val tparams = self.symbol.typeParams
337
- val prefix = self.prefix
338
- val owner = self.symbol.owner
339
- HKTypeLambda (tparams.map(_.paramName))(
340
- tl => tparams.map(p => HKTypeLambda .toPInfo(tl.integrate(tparams, p.info.asSeenFrom(prefix, owner)))),
341
- tl => tl.integrate(tparams, self.appliedTo(tparams.map(_.paramRef))))
342
- case _ => etaExpand(typeParams)
343
-
344
344
/** Maps [Ts] => C[Ts] to C */
345
345
def etaCollapse (using Context ): Type = self match
346
346
case EtaExpansion (classType) => classType
0 commit comments