From eff34242744052452f2e983757d15e522b950aee Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 6 Feb 2024 16:54:40 +0000 Subject: [PATCH] Short-circuit isCheckable with classSymbol A mutually recursive, and ever-growing type pair like ExprMap and EM (in the test case) would blow up isCheckable. Let's use the classSymbol instead. --- .../dotty/tools/dotc/transform/patmat/Space.scala | 4 ++-- tests/pos/i19433.scala | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/pos/i19433.scala diff --git a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala index 9bf852084cfe..b7d60f57c757 100644 --- a/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala +++ b/compiler/src/dotty/tools/dotc/transform/patmat/Space.scala @@ -773,7 +773,7 @@ object SpaceEngine { } private def exhaustivityCheckable(sel: Tree)(using Context): Boolean = { - val seen = collection.mutable.Set.empty[Type] + val seen = collection.mutable.Set.empty[Symbol] // Possible to check everything, but be compatible with scalac by default def isCheckable(tp: Type): Boolean = @@ -789,7 +789,7 @@ object SpaceEngine { tpw.isRef(defn.BooleanClass) || classSym.isAllOf(JavaEnum) || classSym.is(Case) && { - if seen.add(tpw) then productSelectorTypes(tpw, sel.srcPos).exists(isCheckable(_)) + if seen.add(classSym) then productSelectorTypes(tpw, sel.srcPos).exists(isCheckable(_)) else true // recursive case class: return true and other members can still fail the check } diff --git a/tests/pos/i19433.scala b/tests/pos/i19433.scala new file mode 100644 index 000000000000..a16aeb75f2d5 --- /dev/null +++ b/tests/pos/i19433.scala @@ -0,0 +1,12 @@ +// minimised from github.com/Adam-Vandervorst/CZ2 + +import scala.collection.mutable + +private trait EMImpl[V, F[_]] + +case class EM[V2](apps: ExprMap[ExprMap[V2]]) extends EMImpl[V2, EM]: + def collect[W](pf: PartialFunction[V2, W]): Unit = + val apps1 = apps.collect(_.collect(pf)) + +case class ExprMap[V](var em: EM[V] = null) extends EMImpl[V, ExprMap]: + def collect[W](pf: PartialFunction[V, W]): ExprMap[W] = ??? // was: StackOverflow in isCheckable