@@ -2808,8 +2808,22 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2808
2808
val optGadtBounds = gadtBounds(sym)
2809
2809
if optGadtBounds != null then disjointnessBoundary(optGadtBounds.hi)
2810
2810
else disjointnessBoundary(tp.superTypeNormalized)
2811
- case tp @ AppliedType (tycon : TypeRef , _) if tycon.symbol.isClass =>
2812
- tp
2811
+ case tp @ AppliedType (tycon : TypeRef , targs) if tycon.symbol.isClass =>
2812
+ /* The theory says we should just return `tp` here. However, due to how
2813
+ * baseType works (called from `isBaseTypeWithDisjointArguments`),
2814
+ * it can create infinitely growing towers of `AnnotatedType`s. This
2815
+ * defeats the infinite recursion detection with the `pending` set.
2816
+ * Therefore, we eagerly remove all non-refining annotations. We are
2817
+ * allowed to do that because they don't affect subtyping (so cannot
2818
+ * create an ill-kinded `AppliedType`) and would anyway be stripped
2819
+ * later on by the recursive calls to `provablyDisjoint`, though
2820
+ * `disjointnessBoundary`).
2821
+ * See tests/pos/provably-disjoint-infinite-recursion-1.scala for an example.
2822
+ */
2823
+ tp.derivedAppliedType(
2824
+ tycon,
2825
+ targs.mapConserve(_.stripAnnots(keep = _.symbol.derivesFrom(defn.RefiningAnnotationClass )))
2826
+ )
2813
2827
case tp : TermRef =>
2814
2828
val isEnumValue = tp.termSymbol.isAllOf(EnumCase , butNot = JavaDefined )
2815
2829
if isEnumValue then tp
@@ -2957,7 +2971,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
2957
2971
cls.children.map { child =>
2958
2972
if child.isTerm then child.info.classSymbol
2959
2973
else child
2960
- }
2974
+ }.filter(_ != cls)
2961
2975
2962
2976
// TODO? Special-case for Nothing and Null? We probably need Nothing/Null disjoint from Nothing/Null
2963
2977
def eitherDerivesFromOther (cls1 : Symbol , cls2 : Symbol ): Boolean =
0 commit comments