@@ -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,21 +898,29 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
898
898
899
899
canWidenAbstract && acc(true , tp)
900
900
901
- def tryBaseType (cls2 : Symbol ) = {
901
+ def tryBaseType (cls2 : Symbol ) =
902
902
val base = nonExprBaseType(tp1, cls2).boxedIfTypeParam(tp1.typeSymbol)
903
903
if base.exists && (base ne tp1)
904
904
&& (! caseLambda.exists
905
905
|| widenAbstractOKFor(tp2)
906
906
|| tp1.widen.underlyingClassRef(refinementOK = true ).exists)
907
907
then
908
- isSubType(base, tp2, if (tp1.isRef(cls2)) approx else approx.addLow)
909
- && recordGadtUsageIf { MatchType .thatReducesUsingGadt(tp1) }
910
- || base.isInstanceOf [OrType ] && fourthTry
911
- // if base is a disjunction, this might have come from a tp1 type that
908
+ def checkBase =
909
+ isSubType(base, tp2, if tp1.isRef(cls2) then approx else approx.addLow)
910
+ && recordGadtUsageIf { MatchType .thatReducesUsingGadt(tp1) }
911
+ if tp1.widenDealias.isInstanceOf [AndType ] || base.isInstanceOf [OrType ] then
912
+ // If tp1 is a intersection, it could be that one of the original
913
+ // branches of the AndType tp1 conforms to tp2, but its base type does
914
+ // not, or else that its base type for cls2 does not exist, in which case
915
+ // it would not show up in `base`. In either case, we need to also fall back
916
+ // to fourthTry. Test cases are i18266.scala and i18226a.scala.
917
+ // If base is a disjunction, this might have come from a tp1 type that
912
918
// expands to a match type. In this case, we should try to reduce the type
913
919
// and compare the redux. This is done in fourthTry
920
+ either(checkBase, fourthTry)
921
+ else
922
+ checkBase
914
923
else fourthTry
915
- }
916
924
917
925
def fourthTry : Boolean = tp1 match {
918
926
case tp1 : TypeRef =>
@@ -989,7 +997,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
989
997
}
990
998
}
991
999
compareHKLambda
992
- case AndType (tp11, tp12) =>
1000
+ case tp1 @ AndType (tp11, tp12) =>
993
1001
val tp2a = tp2.dealiasKeepRefiningAnnots
994
1002
if (tp2a ne tp2) // Follow the alias; this might avoid truncating the search space in the either below
995
1003
return recur(tp1, tp2a)
@@ -1009,8 +1017,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1009
1017
return recur(AndType (tp11, tp121), tp2) && recur(AndType (tp11, tp122), tp2)
1010
1018
case _ =>
1011
1019
}
1012
- val tp1norm = simplifyAndTypeWithFallback(tp11, tp12, tp1)
1013
- if ( tp1 ne tp1norm) recur(tp1norm, tp2)
1020
+ val tp1norm = trySimplify( tp1)
1021
+ if tp1 ne tp1norm then recur(tp1norm, tp2)
1014
1022
else either(recur(tp11, tp2), recur(tp12, tp2))
1015
1023
case tp1 : MatchType =>
1016
1024
def compareMatch = tp2 match {
@@ -2506,8 +2514,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2506
2514
final def andType (tp1 : Type , tp2 : Type , isErased : Boolean = ctx.erasedTypes): Type =
2507
2515
andTypeGen(tp1, tp2, AndType .balanced(_, _), isErased = isErased)
2508
2516
2509
- final def simplifyAndTypeWithFallback (tp1 : Type , tp2 : Type , fallback : Type ): Type =
2510
- andTypeGen(tp1, tp2, (_, _) => fallback)
2517
+ /** Try to simplify AndType, or return the type itself if no simplifiying opportunities exist. */
2518
+ private def trySimplify (tp : AndType ): Type =
2519
+ andTypeGen(tp.tp1, tp.tp2, (_, _) => tp)
2511
2520
2512
2521
/** Form a normalized conjunction of two types.
2513
2522
* Note: For certain types, `|` is distributed inside the type. This holds for
0 commit comments