@@ -167,11 +167,11 @@ object TypeApplications {
167
167
}
168
168
}
169
169
170
- /** Adapt all arguments to possible higher-kinded type parameters using adaptIfHK
170
+ /** Adapt all arguments to possible higher-kinded type parameters using etaExpandIfHK
171
171
*/
172
- def adaptArgs (tparams : List [Symbol ], args : List [Type ])(implicit ctx : Context ): List [Type ] =
172
+ def etaExpandIfHK (tparams : List [Symbol ], args : List [Type ])(implicit ctx : Context ): List [Type ] =
173
173
if (tparams.isEmpty) args
174
- else args.zipWithConserve(tparams)((arg, tparam) => arg.adaptIfHK (tparam.infoOrCompleter))
174
+ else args.zipWithConserve(tparams)((arg, tparam) => arg.etaExpandIfHK (tparam.infoOrCompleter))
175
175
176
176
def argRefs (rt : RefinedType , n : Int )(implicit ctx : Context ) =
177
177
List .range(0 , n).map(i => RefinedThis (rt).select(tpnme.hkArg(i)))
@@ -340,11 +340,21 @@ class TypeApplications(val self: Type) extends AnyVal {
340
340
self.EtaExpand (self.typeParams)
341
341
}
342
342
343
- /** Adapt argument A to type parameter P in the case P is higher-kinded.
344
- * This means:
345
- * (1) Make sure that A is a type lambda, if necessary by eta-expanding it.
346
- * (2) Make sure the variances of the type lambda
347
- * agrees with variances of corresponding higherkinded type parameters. Example:
343
+ /** Eta expand if `self` is a (non-lambda) class reference and `bound` is a higher-kinded type */
344
+ def etaExpandIfHK (bound : Type )(implicit ctx : Context ): Type = {
345
+ val boundLambda = bound.LambdaTrait
346
+ val hkParams = boundLambda.typeParams
347
+ if (hkParams.isEmpty) self
348
+ else self match {
349
+ case self : TypeRef if self.symbol.isClass && self.typeParams.length == hkParams.length =>
350
+ EtaExpansion (self)
351
+ case _ => self
352
+ }
353
+ }
354
+
355
+ /** If argument A and type parameter P are higher-kinded, adapt the variances
356
+ * of A to those of P, ensuring that the variances of the type lambda A
357
+ * agree with the variances of corresponding higherkinded type parameters of P. Example:
348
358
*
349
359
* class Companion[+CC[X]]
350
360
* Companion[List]
@@ -367,25 +377,26 @@ class TypeApplications(val self: Type) extends AnyVal {
367
377
* and the second is not a subtype of the first. So if we have overridding memebrs of the two
368
378
* types we get an error.
369
379
*/
370
- def adaptIfHK (bound : Type )(implicit ctx : Context ): Type = {
380
+ def adaptHkVariances (bound : Type )(implicit ctx : Context ): Type = {
371
381
val boundLambda = bound.LambdaTrait
372
382
val hkParams = boundLambda.typeParams
373
383
if (hkParams.isEmpty) self
374
- else self match {
375
- case self : TypeRef if self.symbol.isClass && self.typeParams.length == hkParams.length =>
376
- EtaExpansion (self).adaptIfHK(bound)
377
- case _ =>
378
- def adaptArg (arg : Type ): Type = arg match {
379
- case arg : TypeRef
380
- if arg.symbol.isLambdaTrait &&
381
- ! arg.symbol.typeParams.corresponds(boundLambda.typeParams)(_.variance == _.variance) =>
382
- arg.prefix.select(boundLambda)
383
- case arg : RefinedType =>
384
- arg.derivedRefinedType(adaptArg(arg.parent), arg.refinedName, arg.refinedInfo)
385
- case _ =>
386
- arg
387
- }
388
- adaptArg(self)
384
+ else {
385
+ def adaptArg (arg : Type ): Type = arg match {
386
+ case arg : TypeRef if arg.symbol.isLambdaTrait &&
387
+ ! arg.symbol.typeParams.corresponds(hkParams)(_.variance == _.variance) &&
388
+ arg.symbol.typeParams.corresponds(hkParams)(varianceConforms) =>
389
+ arg.prefix.select(boundLambda)
390
+ case arg : RefinedType =>
391
+ arg.derivedRefinedType(adaptArg(arg.parent), arg.refinedName, arg.refinedInfo)
392
+ case arg @ TypeAlias (alias) =>
393
+ arg.derivedTypeAlias(adaptArg(alias))
394
+ case arg @ TypeBounds (lo, hi) =>
395
+ arg.derivedTypeBounds(lo, adaptArg(hi))
396
+ case _ =>
397
+ arg
398
+ }
399
+ adaptArg(self)
389
400
}
390
401
}
391
402
0 commit comments