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