@@ -431,18 +431,25 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
431431 case Some (b) => return b
432432 case None =>
433433
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+
434441 def widenOK =
435442 (tp2.widenSingletons eq tp2)
436443 && (tp1.widenSingletons ne tp1)
437- && recur (tp1.widenSingletons, tp2)
444+ && recurInFrozenGadt (tp1.widenSingletons, tp2)
438445
439446 def joinOK = tp2.dealiasKeepRefiningAnnots match {
440447 case tp2 : AppliedType if ! tp2.tycon.typeSymbol.isClass =>
441448 // If we apply the default algorithm for `A[X] | B[Y] <: C[Z]` where `C` is a
442449 // type parameter, we will instantiate `C` to `A` and then fail when comparing
443450 // with `B[Y]`. To do the right thing, we need to instantiate `C` to the
444451 // common superclass of `A` and `B`.
445- recur (tp1.join, tp2)
452+ recurInFrozenGadt (tp1.join, tp2)
446453 case _ =>
447454 false
448455 }
@@ -469,7 +476,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
469476 widenOK
470477 || joinOK
471478 || (tp1.isSoft || constrainRHSVars(tp2)) && recur(tp11, tp2) && recur(tp12, tp2)
472- || containsAnd(tp1) && recur (tp1.join, tp2)
479+ || containsAnd(tp1) && recurInFrozenGadt (tp1.join, tp2)
473480 case tp1 : MatchType =>
474481 val reduced = tp1.reduced
475482 if (reduced.exists) recur(reduced, tp2) else thirdTry
0 commit comments