@@ -446,7 +446,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
446
446
case tp2 : HKTypeLambda =>
447
447
def compareTypeLambda : Boolean = tp1.stripTypeVar match {
448
448
case tp1 : HKTypeLambda =>
449
- /* Don't compare bounds of lambdas under language:Scala2, or t2994 will fail
449
+ /* Don't compare bounds or variances of lambdas under language:Scala2.
450
+ * (1) If we compare bounds, t2994 will fail.
450
451
* The issue is that, logically, bounds should compare contravariantly,
451
452
* but that would invalidate a pattern exploited in t2994:
452
453
*
@@ -458,17 +459,32 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
458
459
*
459
460
* Note: it would be nice if this could trigger a migration warning, but I
460
461
* am not sure how, since the code is buried so deep in subtyping logic.
462
+ *
463
+ * (2) If we compare variances, compilation of scala.collection.mutable.Set wil fail.
464
+ * The issue is the following:
465
+ *
466
+ * Error overriding method companion in trait Iterable of type
467
+ * => scala.collection.generic.GenericCompanion[[+A] => scala.collection.Iterable[A]];
468
+ * method companion of type
469
+ * => scala.collection.generic.GenericCompanion[[A] => scala.collection.mutable.Set[A]]
470
+ * has incompatible type.
471
+ *
472
+ * Indeed, a non-variant Set is not a legal substitute for a covariant Iterable.
473
+ * Every instantiated Set is an Iterable, but the type constructor Iterable can be
474
+ * passed to a covariant type constructor CC[+X] whereas a non-variant Set cannot.
461
475
*/
462
476
def boundsOK =
463
477
ctx.scala2Mode ||
464
478
tp1.typeParams.corresponds(tp2.typeParams)((tparam1, tparam2) =>
465
479
isSubType(tparam2.paramInfo.subst(tp2, tp1), tparam1.paramInfo))
480
+ def variancesOK =
481
+ ctx.scala2Mode ||
482
+ variancesConform(tp1.typeParams, tp2.typeParams)
466
483
val saved = comparedTypeLambdas
467
484
comparedTypeLambdas += tp1
468
485
comparedTypeLambdas += tp2
469
486
try
470
- variancesConform(tp1.typeParams, tp2.typeParams) &&
471
- boundsOK &&
487
+ variancesOK && boundsOK &&
472
488
isSubType(tp1.resType, tp2.resType.subst(tp2, tp1))
473
489
finally comparedTypeLambdas = saved
474
490
case _ =>
0 commit comments