Skip to content

Commit e295c1f

Browse files
authored
Merge pull request #14880 from dotty-staging/fix-14870
2 parents 70c6d1f + a6eac21 commit e295c1f

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
158158
private inline def inFrozenGadt[T](inline op: T): T =
159159
inFrozenGadtIf(true)(op)
160160

161+
/** A flag to prevent recursive joins when comparing AndTypes on the left */
162+
private var joined = false
163+
161164
private inline def inFrozenGadtIf[T](cond: Boolean)(inline op: T): T = {
162165
val savedFrozenGadt = frozenGadt
163166
frozenGadt ||= cond
@@ -477,11 +480,20 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
477480
widenOK
478481
|| joinOK
479482
|| (tp1.isSoft || constrainRHSVars(tp2)) && recur(tp11, tp2) && recur(tp12, tp2)
480-
|| containsAnd(tp1) && inFrozenGadt(recur(tp1.join, tp2))
483+
|| containsAnd(tp1)
484+
&& !joined
485+
&& {
486+
joined = true
487+
try inFrozenGadt(recur(tp1.join, tp2))
488+
finally joined = false
489+
}
481490
// An & on the left side loses information. We compensate by also trying the join.
482491
// This is less ad-hoc than it looks since we produce joins in type inference,
483492
// and then need to check that they are indeed supertypes of the original types
484493
// under -Ycheck. Test case is i7965.scala.
494+
// On the other hand, we could get a combinatorial explosion by applying such joins
495+
// recursively, so we do it only once. See i14870.scala as a test case, which would
496+
// loop for a very long time without the recursion brake.
485497

486498
case tp1: MatchType =>
487499
val reduced = tp1.reduced
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
abstract class Quantity[A <: Quantity[A]]
2+
class Energy extends Quantity[Energy]
3+
class Time extends Quantity[Time]
4+
class Dimensionless extends Quantity[Dimensionless]
5+
6+
class Price[Q <: Quantity[Q] & (Energy | Time | Dimensionless)]

0 commit comments

Comments
 (0)