@@ -478,7 +478,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
478
478
tp2.isRef(AnyClass , skipRefined = false )
479
479
|| ! tp1.evaluating && recur(tp1.ref, tp2)
480
480
case AndType (tp11, tp12) =>
481
- if ( tp11.stripTypeVar eq tp12.stripTypeVar) recur(tp11, tp2)
481
+ if tp11.stripTypeVar eq tp12.stripTypeVar then recur(tp11, tp2)
482
482
else thirdTry
483
483
case tp1 @ OrType (tp11, tp12) =>
484
484
compareAtoms(tp1, tp2) match
@@ -898,8 +898,27 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
898
898
899
899
canWidenAbstract && acc(true , tp)
900
900
901
- def tryBaseType (cls2 : Symbol ) = {
902
- val base = nonExprBaseType(tp1, cls2).boxedIfTypeParam(tp1.typeSymbol)
901
+ def tryBaseType (cls2 : Symbol ) =
902
+
903
+ def computeBase (tp : Type ): Type = tp.widenDealias match
904
+ case tp @ AndType (tp1, tp2) =>
905
+ // We have to treat AndTypes specially, since the normal treatment
906
+ // of `(T1 & T2).baseType(C)` combines the base types of T1 and T2 via glb
907
+ // which drops any types that don't exist. That forgets possible solutions.
908
+ // For instance, in i18266.scala, we get to a subgoal `R & Row[Int] <: Row[String]`
909
+ // where R is an uninstantiated type variable. The base type computation
910
+ // of the LHS drops the non-existing base type of R and results in
911
+ // `Row[Int]`, which leads to a subtype failure since `Row[Int] <: Row[String]`
912
+ // does not hold. The new strategy is to declare that the base type computation
913
+ // failed since R does not have a base type, and to proceed to fourthTry instead,
914
+ // where we try both sides of an AndType individually.
915
+ val b1 = computeBase(tp1)
916
+ val b2 = computeBase(tp2)
917
+ if b1.exists && b2.exists then tp.derivedAndType(b1, b2) else NoType
918
+ case _ =>
919
+ nonExprBaseType(tp, cls2).boxedIfTypeParam(tp.typeSymbol)
920
+
921
+ val base = computeBase(tp1)
903
922
if base.exists && (base ne tp1)
904
923
&& (! caseLambda.exists
905
924
|| widenAbstractOKFor(tp2)
@@ -912,7 +931,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
912
931
// expands to a match type. In this case, we should try to reduce the type
913
932
// and compare the redux. This is done in fourthTry
914
933
else fourthTry
915
- }
934
+ end tryBaseType
916
935
917
936
def fourthTry : Boolean = tp1 match {
918
937
case tp1 : TypeRef =>
@@ -989,7 +1008,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
989
1008
}
990
1009
}
991
1010
compareHKLambda
992
- case AndType (tp11, tp12) =>
1011
+ case tp1 @ AndType (tp11, tp12) =>
993
1012
val tp2a = tp2.dealiasKeepRefiningAnnots
994
1013
if (tp2a ne tp2) // Follow the alias; this might avoid truncating the search space in the either below
995
1014
return recur(tp1, tp2a)
@@ -1009,8 +1028,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1009
1028
return recur(AndType (tp11, tp121), tp2) && recur(AndType (tp11, tp122), tp2)
1010
1029
case _ =>
1011
1030
}
1012
- val tp1norm = simplifyAndTypeWithFallback(tp11, tp12, tp1)
1013
- if ( tp1 ne tp1norm) recur(tp1norm, tp2)
1031
+ val tp1norm = trySimplify( tp1)
1032
+ if tp1 ne tp1norm then recur(tp1norm, tp2)
1014
1033
else either(recur(tp11, tp2), recur(tp12, tp2))
1015
1034
case tp1 : MatchType =>
1016
1035
def compareMatch = tp2 match {
@@ -2506,8 +2525,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2506
2525
final def andType (tp1 : Type , tp2 : Type , isErased : Boolean = ctx.erasedTypes): Type =
2507
2526
andTypeGen(tp1, tp2, AndType .balanced(_, _), isErased = isErased)
2508
2527
2509
- final def simplifyAndTypeWithFallback (tp1 : Type , tp2 : Type , fallback : Type ): Type =
2510
- andTypeGen(tp1, tp2, (_, _) => fallback)
2528
+ /** Try to simplify AndType, or return the type itself if no simplifiying opportunities exist. */
2529
+ private def trySimplify (tp : AndType ): Type =
2530
+ andTypeGen(tp.tp1, tp.tp2, (_, _) => tp)
2511
2531
2512
2532
/** Form a normalized conjunction of two types.
2513
2533
* Note: For certain types, `|` is distributed inside the type. This holds for
0 commit comments