@@ -573,11 +573,25 @@ class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] {
573
573
}
574
574
compareTypeLambda
575
575
case OrType (tp21, tp22) =>
576
+ // The next clause handles a situation like the one encountered in i2745.scala.
577
+ // We have:
578
+ //
579
+ // x: A | B, x.type <:< A | X where X is a type variable
580
+ //
581
+ // We should instantiate X to B instead of x.type or A | B. To do this, we widen
582
+ // the LHS to A | B and recur *without indicating that this is a lowApprox*. The
583
+ // latter point is important since otherwise we would not get to instantiate X.
584
+ // If that succeeds, fine. If not we continue and hit the `either` below.
585
+ // That second path is important to handle comparisons with unions of singletons,
586
+ // as in `1 <:< 1 | 2`.
576
587
val tp1w = tp1.widen
577
- val tp1a = tp1w.dealiasKeepRefiningAnnots
588
+ if ((tp1w ne tp1) && recur(tp1w, tp2))
589
+ return true
590
+
591
+ val tp1a = tp1.dealiasKeepRefiningAnnots
578
592
if (tp1a ne tp1)
579
- // Follow the alias; this might avoid truncating the search space in the either below
580
- return recur(tp1a, tp2) || (tp1w ne tp1) && isSubType(tp1w, tp2, approx.addLow)
593
+ // Follow the alias; this might lead to an OrType on the left which needs to be split
594
+ return recur(tp1a, tp2)
581
595
582
596
// Rewrite T1 <: (T211 & T212) | T22 to T1 <: (T211 | T22) and T1 <: (T212 | T22)
583
597
// and analogously for T1 <: T21 | (T221 & T222)
0 commit comments