@@ -478,7 +478,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
478478 tp2.isRef(AnyClass , skipRefined = false )
479479 || ! tp1.evaluating && recur(tp1.ref, tp2)
480480 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)
482482 else thirdTry
483483 case tp1 @ OrType (tp11, tp12) =>
484484 compareAtoms(tp1, tp2) match
@@ -898,21 +898,29 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
898898
899899 canWidenAbstract && acc(true , tp)
900900
901- def tryBaseType (cls2 : Symbol ) = {
901+ def tryBaseType (cls2 : Symbol ) =
902902 val base = nonExprBaseType(tp1, cls2).boxedIfTypeParam(tp1.typeSymbol)
903903 if base.exists && (base ne tp1)
904904 && (! caseLambda.exists
905905 || widenAbstractOKFor(tp2)
906906 || tp1.widen.underlyingClassRef(refinementOK = true ).exists)
907907 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
912918 // expands to a match type. In this case, we should try to reduce the type
913919 // and compare the redux. This is done in fourthTry
920+ either(checkBase, fourthTry)
921+ else
922+ checkBase
914923 else fourthTry
915- }
916924
917925 def fourthTry : Boolean = tp1 match {
918926 case tp1 : TypeRef =>
@@ -989,7 +997,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
989997 }
990998 }
991999 compareHKLambda
992- case AndType (tp11, tp12) =>
1000+ case tp1 @ AndType (tp11, tp12) =>
9931001 val tp2a = tp2.dealiasKeepRefiningAnnots
9941002 if (tp2a ne tp2) // Follow the alias; this might avoid truncating the search space in the either below
9951003 return recur(tp1, tp2a)
@@ -1009,8 +1017,8 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
10091017 return recur(AndType (tp11, tp121), tp2) && recur(AndType (tp11, tp122), tp2)
10101018 case _ =>
10111019 }
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)
10141022 else either(recur(tp11, tp2), recur(tp12, tp2))
10151023 case tp1 : MatchType =>
10161024 def compareMatch = tp2 match {
@@ -2506,8 +2514,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
25062514 final def andType (tp1 : Type , tp2 : Type , isErased : Boolean = ctx.erasedTypes): Type =
25072515 andTypeGen(tp1, tp2, AndType .balanced(_, _), isErased = isErased)
25082516
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)
25112520
25122521 /** Form a normalized conjunction of two types.
25132522 * Note: For certain types, `|` is distributed inside the type. This holds for
0 commit comments