Skip to content

Commit 5101d18

Browse files
committed
Don't check variances when comparing type lambdas in Scala2 mode
There were some failures when compiling stdlib. It's explained in the code comment.
1 parent 825f7eb commit 5101d18

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
446446
case tp2: HKTypeLambda =>
447447
def compareTypeLambda: Boolean = tp1.stripTypeVar match {
448448
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.
450451
* The issue is that, logically, bounds should compare contravariantly,
451452
* but that would invalidate a pattern exploited in t2994:
452453
*
@@ -458,17 +459,32 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
458459
*
459460
* Note: it would be nice if this could trigger a migration warning, but I
460461
* 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.
461475
*/
462476
def boundsOK =
463477
ctx.scala2Mode ||
464478
tp1.typeParams.corresponds(tp2.typeParams)((tparam1, tparam2) =>
465479
isSubType(tparam2.paramInfo.subst(tp2, tp1), tparam1.paramInfo))
480+
def variancesOK =
481+
ctx.scala2Mode ||
482+
variancesConform(tp1.typeParams, tp2.typeParams)
466483
val saved = comparedTypeLambdas
467484
comparedTypeLambdas += tp1
468485
comparedTypeLambdas += tp2
469486
try
470-
variancesConform(tp1.typeParams, tp2.typeParams) &&
471-
boundsOK &&
487+
variancesOK && boundsOK &&
472488
isSubType(tp1.resType, tp2.resType.subst(tp2, tp1))
473489
finally comparedTypeLambdas = saved
474490
case _ =>

0 commit comments

Comments
 (0)