Skip to content

Commit 81b7ed9

Browse files
committed
isSubtype: try to dealias TypeRefs before recursively checking the prefixes
As demonstrated by tests/pos/hk-deep-subtype.scala, we can avoid some deep subtype recursions that result in stack overflows by doing this. Fix #943.
1 parent 4463f5e commit 81b7ed9

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,15 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
144144
case info2: TypeAlias => isSubType(tp1, info2.alias)
145145
case _ => info1 match {
146146
case info1: TypeAlias => isSubType(info1.alias, tp2)
147-
case NoType => secondTry(tp1, tp2)
148-
case _ => thirdTryNamed(tp1, tp2)
147+
case _ => false
149148
}
150149
}
151150
def compareNamed = {
152151
implicit val ctx: Context = this.ctx // Dotty deviation: implicits need explicit type
153152
tp1 match {
154153
case tp1: NamedType =>
155154
val sym1 = tp1.symbol
155+
compareAlias(tp1.info) ||
156156
(if ((sym1 ne NoSymbol) && (sym1 eq tp2.symbol))
157157
ctx.erasedTypes || sym1.isStaticOwner || isSubType(tp1.prefix, tp2.prefix)
158158
else
@@ -164,10 +164,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
164164
) ||
165165
compareHK(tp1, tp2, inOrder = true) ||
166166
compareHK(tp2, tp1, inOrder = false) ||
167-
compareAlias(tp1.info)
167+
thirdTryNamed(tp1, tp2)
168168
case _ =>
169169
compareHK(tp2, tp1, inOrder = false) ||
170-
compareAlias(NoType)
170+
compareAlias(NoType) ||
171+
secondTry(tp1, tp2)
171172
}
172173
}
173174
compareNamed

test/dotc/scala-collections.whitelist

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,13 @@
263263
./scala-scala/src/library/scala/collection/generic/GenericSeqCompanion.scala
264264
./scala-scala/src/library/scala/collection/generic/GenericSetTemplate.scala
265265

266-
# deep subtype
267-
#./scala-scala/src/library/scala/collection/generic/GenericTraversableTemplate.scala
266+
./scala-scala/src/library/scala/collection/generic/GenericTraversableTemplate.scala
268267

269268
./scala-scala/src/library/scala/collection/generic/HasNewBuilder.scala
270269
./scala-scala/src/library/scala/collection/generic/HasNewCombiner.scala
271270

272-
# https://github.com/lampepfl/dotty/issues/943
273-
# [error] Test dotc.tests.compileStdLib failed: java.lang.Error: deep subtype, took 6.462 sec
274-
#./scala-scala/src/library/scala/collection/generic/ImmutableMapFactory.scala
275-
#./scala-scala/src/library/scala/collection/generic/ImmutableSetFactory.scala
271+
./scala-scala/src/library/scala/collection/generic/ImmutableMapFactory.scala
272+
./scala-scala/src/library/scala/collection/generic/ImmutableSetFactory.scala
276273

277274
./scala-scala/src/library/scala/collection/generic/ImmutableSortedMapFactory.scala
278275
./scala-scala/src/library/scala/collection/generic/ImmutableSortedSetFactory.scala

tests/pos/hk-deep-subtype.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Minimized from scala.collection.generic.GenTraversableFactory plus dependencies
2+
import scala.annotation.unchecked.uncheckedVariance
3+
4+
trait GT[A] extends GTT[A, GT]
5+
6+
trait HNB[B]
7+
trait GTT[+C, DD[X] <: GT[X]] extends HNB[DD[C] @uncheckedVariance] // Can be any annotation and still crash
8+
9+
class GTF[EE[X] <: GT[X] with GTT[X, EE]]
10+
{
11+
def foo[F]: EE[F] = ???
12+
def bar[G](f: G): EE[G] = ???
13+
14+
def tabulate: EE[EE[Int]] = bar(foo)
15+
}

0 commit comments

Comments
 (0)