@@ -3201,14 +3201,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
3201
3201
result
3202
3202
end existsCommonBaseTypeWithDisjointArguments
3203
3203
3204
- provablyDisjointClasses(cls1, cls2)
3204
+ provablyDisjointClasses(cls1, cls2, seen = null )
3205
3205
|| existsCommonBaseTypeWithDisjointArguments
3206
3206
end match
3207
3207
}
3208
3208
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 =
3210
3210
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
3212
3213
3213
3214
def decompose (cls : Symbol ): List [Symbol ] =
3214
3215
cls.children.flatMap { child =>
@@ -3217,6 +3218,13 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
3217
3218
else child :: Nil
3218
3219
}.filter(child => child.exists && child != cls)
3219
3220
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
+
3220
3228
def eitherDerivesFromOther (cls1 : Symbol , cls2 : Symbol ): Boolean =
3221
3229
cls1.derivesFrom(cls2) || cls2.derivesFrom(cls1)
3222
3230
@@ -3239,9 +3247,11 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
3239
3247
// instantiations of `cls1` (terms of the form `new cls1`) are not
3240
3248
// of type `tp2`. Therefore, we can safely decompose `cls1` using
3241
3249
// `.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))
3243
3252
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))
3245
3255
else
3246
3256
false
3247
3257
end provablyDisjointClasses
0 commit comments