@@ -3201,14 +3201,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
32013201 result
32023202 end existsCommonBaseTypeWithDisjointArguments
32033203
3204- provablyDisjointClasses(cls1, cls2)
3204+ provablyDisjointClasses(cls1, cls2, seen = null )
32053205 || existsCommonBaseTypeWithDisjointArguments
32063206 end match
32073207 }
32083208
3209- private def provablyDisjointClasses (cls1 : Symbol , cls2 : Symbol )(using Context ): Boolean =
3209+ private def provablyDisjointClasses (cls1 : Symbol , cls2 : Symbol , seen : util. HashSet [ Symbol ] | Null )(using Context ): Boolean =
32103210 def isDecomposable (cls : Symbol ): Boolean =
3211- cls.is(Sealed ) && ! cls.hasAnonymousChild
3211+ if seen != null && seen.contains(cls) then false
3212+ else cls.is(Sealed ) && ! cls.hasAnonymousChild
32123213
32133214 def decompose (cls : Symbol ): List [Symbol ] =
32143215 cls.children.flatMap { child =>
@@ -3217,6 +3218,13 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
32173218 else child :: Nil
32183219 }.filter(child => child.exists && child != cls)
32193220
3221+ inline def seeing (inline cls : Symbol )(inline thunk : util.HashSet [Symbol ] => Boolean ) =
3222+ val seen1 = if seen == null then new util.HashSet [Symbol ] else seen
3223+ try
3224+ seen1 += cls
3225+ thunk(seen1)
3226+ finally seen1 -= cls
3227+
32203228 def eitherDerivesFromOther (cls1 : Symbol , cls2 : Symbol ): Boolean =
32213229 cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1)
32223230
@@ -3239,9 +3247,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
32393247 // instantiations of `cls1` (terms of the form `new cls1`) are not
32403248 // of type `tp2`. Therefore, we can safely decompose `cls1` using
32413249 // `.children`, even if `cls1` is non abstract.
3242- decompose(cls1).forall(x => provablyDisjointClasses(x, cls2))
3250+ seeing(cls1): seen1 =>
3251+ decompose(cls1).forall(x => provablyDisjointClasses(x, cls2, seen1))
32433252 else if (isDecomposable(cls2))
3244- decompose(cls2).forall(x => provablyDisjointClasses(cls1, x))
3253+ seeing(cls2): seen1 =>
3254+ decompose(cls2).forall(x => provablyDisjointClasses(cls1, x, seen1))
32453255 else
32463256 false
32473257 end provablyDisjointClasses
0 commit comments