@@ -431,18 +431,25 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
431
431
case Some (b) => return b
432
432
case None =>
433
433
434
+ /** `recur` shouldn't normally be used with approximated types, according to its
435
+ * documentation. In the specific examples where this function is
436
+ * called, it is sound to do so as long as we freeze GADTs.
437
+ */
438
+ def recurInFrozenGadt (tp1 : Type , tp2 : Type ) =
439
+ inFrozenGadt { recur(tp1, tp2) }
440
+
434
441
def widenOK =
435
442
(tp2.widenSingletons eq tp2)
436
443
&& (tp1.widenSingletons ne tp1)
437
- && recur (tp1.widenSingletons, tp2)
444
+ && recurInFrozenGadt (tp1.widenSingletons, tp2)
438
445
439
446
def joinOK = tp2.dealiasKeepRefiningAnnots match {
440
447
case tp2 : AppliedType if ! tp2.tycon.typeSymbol.isClass =>
441
448
// If we apply the default algorithm for `A[X] | B[Y] <: C[Z]` where `C` is a
442
449
// type parameter, we will instantiate `C` to `A` and then fail when comparing
443
450
// with `B[Y]`. To do the right thing, we need to instantiate `C` to the
444
451
// common superclass of `A` and `B`.
445
- recur (tp1.join, tp2)
452
+ recurInFrozenGadt (tp1.join, tp2)
446
453
case _ =>
447
454
false
448
455
}
@@ -469,7 +476,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
469
476
widenOK
470
477
|| joinOK
471
478
|| (tp1.isSoft || constrainRHSVars(tp2)) && recur(tp11, tp2) && recur(tp12, tp2)
472
- || containsAnd(tp1) && recur (tp1.join, tp2)
479
+ || containsAnd(tp1) && recurInFrozenGadt (tp1.join, tp2)
473
480
case tp1 : MatchType =>
474
481
val reduced = tp1.reduced
475
482
if (reduced.exists) recur(reduced, tp2) else thirdTry
0 commit comments