Skip to content

Commit 6e4b4f4

Browse files
committed
TypeComparer: delay looking up members of AndTypes
In ParFactory.scala we have checks that look like: (Foo { type Bar = X }) & (Foo { type Bar = X }) <:< (Foo { type Bar = X }) where `Foo` is a recursive type. Before this commit, we would first try to check this by looking up `Bar` in the `AndType` on the left, which means looking it up in both branches and then merging the result, but the merge requires more subtyping checks, which in turn require looking up a member inside an `AndType`, seemingly ad infinitum. We now avoid this by checking if either branch of the `AndType` on the left is a subtype of the `RefinedType` on the right before looking up a member in the `AndType` itself.
1 parent 1125646 commit 6e4b4f4

File tree

2 files changed

+14
-10
lines changed

2 files changed

+14
-10
lines changed

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -331,17 +331,23 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
331331
}
332332
comparePolyParam
333333
case tp2: RefinedType =>
334+
def compareRefinedSlow: Boolean = {
335+
val name2 = tp2.refinedName
336+
isSubType(tp1, tp2.parent) &&
337+
(name2 == nme.WILDCARD || hasMatchingMember(name2, tp1, tp2))
338+
}
334339
def compareRefined: Boolean = {
335340
val tp1w = tp1.widen
336341
val skipped2 = skipMatching(tp1w, tp2)
337342
if ((skipped2 eq tp2) || !Config.fastPathForRefinedSubtype) {
338-
val name2 = tp2.refinedName
339-
val normalPath =
340-
isSubType(tp1, tp2.parent) &&
341-
( name2 == nme.WILDCARD
342-
|| hasMatchingMember(name2, tp1, tp2)
343-
|| fourthTry(tp1, tp2)
344-
)
343+
val normalPath = tp1 match {
344+
case tp1: AndType =>
345+
// Delay calling `compareRefinedSlow` because looking up a member
346+
// of an `AndType` can lead to a cascade of subtyping checks
347+
fourthTry(tp1, tp2) || compareRefinedSlow
348+
case _ =>
349+
compareRefinedSlow || fourthTry(tp1, tp2)
350+
}
345351
normalPath ||
346352
needsEtaLift(tp1, tp2) && tp1.testLifted(tp2.typeParams, isSubType(_, tp2), classBounds(tp2))
347353
}

test/dotc/scala-collections.whitelist

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,7 @@
287287
./scala-scala/src/library/scala/collection/generic/SortedMapFactory.scala
288288
./scala-scala/src/library/scala/collection/generic/SortedSetFactory.scala
289289
./scala-scala/src/library/scala/collection/generic/SetFactory.scala
290-
291-
# deep subtype
292-
#./scala-scala/src/library/scala/collection/generic/ParFactory.scala
290+
./scala-scala/src/library/scala/collection/generic/ParFactory.scala
293291

294292
# https://github.com/lampepfl/dotty/issues/974
295293
#./scala-scala/src/library/scala/collection/generic/MutableSortedSetFactory.scala

0 commit comments

Comments
 (0)