@@ -524,29 +524,36 @@ class TypeApplications(val self: Type) extends AnyVal {
524
524
}
525
525
}
526
526
527
- /** Convert a type constructor `TC` with type parameters `T1, ..., Tn` to
527
+ /** Convert a type constructor `TC` which has type parameters `T1, ..., Tn`
528
+ * in a context where type parameters `U1,...,Un` are expected to
528
529
*
529
530
* LambdaXYZ { Apply = TC[hk$0, ..., hk$n] }
530
531
*
531
- * where XYZ is a corresponds to the variances of the type parameters.
532
+ * Here, XYZ corresponds to the variances of
533
+ * - `U1,...,Un` if the variances of `T1,...,Tn` are pairwise compatible with `U1,...,Un`,
534
+ * - `T1,...,Tn` otherwise.
535
+ * v1 is compatible with v2, if v1 = v2 or v2 is non-variant.
532
536
*/
533
- def EtaExpand (implicit ctx : Context ): Type = {
534
- val tparams = typeParams
535
- self.appliedTo(tparams map (_.typeRef)).LambdaAbstract (tparams)
537
+ def EtaExpand (tparams : List [Symbol ])(implicit ctx : Context ): Type = {
538
+ def varianceCompatible (actual : Symbol , formal : Symbol ) =
539
+ formal.variance == 0 || actual.variance == formal.variance
540
+ val tparamsToUse =
541
+ if (typeParams.corresponds(tparams)(varianceCompatible)) tparams else typeParams
542
+ self.appliedTo(tparams map (_.typeRef)).LambdaAbstract (tparamsToUse)
536
543
// .ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
537
544
}
538
545
539
546
/** Eta expand if `bound` is a higher-kinded type */
540
547
def EtaExpandIfHK (bound : Type )(implicit ctx : Context ): Type =
541
- if (bound.isHK && ! isHK && self.typeSymbol.isClass && typeParams.nonEmpty) EtaExpand
548
+ if (bound.isHK && ! isHK && self.typeSymbol.isClass && typeParams.nonEmpty) EtaExpand (bound.typeParams)
542
549
else self
543
550
544
551
/** Eta expand the prefix in front of any refinements. */
545
552
def EtaExpandCore (implicit ctx : Context ): Type = self.stripTypeVar match {
546
553
case self : RefinedType =>
547
554
self.derivedRefinedType(self.parent.EtaExpandCore , self.refinedName, self.refinedInfo)
548
555
case _ =>
549
- self.EtaExpand
556
+ self.EtaExpand (self.typeParams)
550
557
}
551
558
552
559
/** If `self` is a (potentially partially instantiated) eta expansion of type T, return T,
@@ -645,7 +652,7 @@ class TypeApplications(val self: Type) extends AnyVal {
645
652
param2.variance == param2.variance || param2.variance == 0
646
653
if (classBounds.exists(tycon.derivesFrom(_)) &&
647
654
tycon.typeParams.corresponds(tparams)(variancesMatch)) {
648
- val expanded = tycon.EtaExpand
655
+ val expanded = tycon.EtaExpand (tparams)
649
656
val lifted = (expanded /: targs) { (partialInst, targ) =>
650
657
val tparam = partialInst.typeParams.head
651
658
RefinedType (partialInst, tparam.name, targ.bounds.withVariance(tparam.variance))
@@ -659,7 +666,7 @@ class TypeApplications(val self: Type) extends AnyVal {
659
666
false
660
667
}
661
668
tparams.nonEmpty &&
662
- (typeParams.nonEmpty && p(EtaExpand ) ||
669
+ (typeParams.hasSameLengthAs(tparams) && p(EtaExpand (tparams) ) ||
663
670
classBounds.nonEmpty && tryLift(self.baseClasses))
664
671
}
665
672
}
0 commit comments