Skip to content

Commit c1acb7e

Browse files
committed
Extend caching in the space engine beyond local context
Previously isSubspace calls would be cached only as part of individual Space object, so when recursing through their ADT contents, we were not able to reuse the previously computed information. Now the cache is shared across the whole space engine run.
1 parent 4b97d25 commit c1acb7e

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ import SpaceEngine.*
4848
*
4949
*/
5050

51+
/** A key to be used in a context property that caches the unpickled trees */
52+
private val IsSubspaceCacheKey = new Property.Key[mutable.HashMap[(Space, Space), Boolean]]
53+
5154
/** space definition */
5255
sealed trait Space extends Showable:
5356

@@ -60,7 +63,8 @@ sealed trait Space extends Showable:
6063
if (a ne a2) || (b ne b2) then a2.isSubspace(b2)
6164
else if a == Empty then true
6265
else if b == Empty then false
63-
else isSubspaceCache.getOrElseUpdate(b, computeIsSubspace(a, b))
66+
else
67+
ctx.property(IsSubspaceCacheKey).get.getOrElseUpdate((a, b), computeIsSubspace(a, b))
6468

6569
@sharable private var mySimplified: Space | Null = null
6670

@@ -968,6 +972,8 @@ object SpaceEngine {
968972
end checkReachability
969973

970974
def checkMatch(m: Match)(using Context): Unit =
971-
if exhaustivityCheckable(m.selector) then checkExhaustivity(m)
972-
if reachabilityCheckable(m.selector) then checkReachability(m)
975+
inContext(ctx.withProperty(IsSubspaceCacheKey, Some(mutable.HashMap.empty))) {
976+
if exhaustivityCheckable(m.selector) then checkExhaustivity(m)
977+
if reachabilityCheckable(m.selector) then checkReachability(m)
978+
}
973979
}

tests/pos/i23317.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import scala.quoted.*
2+
3+
def goImpl(using Quotes): Expr[Int] =
4+
List.empty[Type[?]] match
5+
case Nil =>
6+
Expr(0)
7+
case '[t1] :: Nil =>
8+
Expr(1)
9+
case '[t1] :: '[t2] :: Nil =>
10+
Expr(2)
11+
case '[t1] :: '[t2] :: '[t3] :: Nil =>
12+
Expr(3)
13+
case '[t1] :: '[t2] :: '[t3] :: '[t4] :: Nil =>
14+
Expr(4)
15+
case '[t1] :: '[t2] :: '[t3] :: '[t4] :: '[t5] :: Nil =>
16+
Expr(5)
17+
case '[t1] :: '[t2] :: '[t3] :: '[t4] :: '[t5] :: '[t6] :: Nil =>
18+
Expr(6)
19+
case '[t1] :: '[t2] :: '[t3] :: '[t4] :: '[t5] :: '[t6] :: '[t7] :: Nil =>
20+
Expr(7)
21+
case '[t1] :: '[t2] :: '[t3] :: '[t4] :: '[t5] :: '[t6] :: '[t7] :: '[t8] :: Nil =>
22+
Expr(8)
23+
case '[t1] :: '[t2] :: '[t3] :: '[t4] :: '[t5] :: '[t6] :: '[t7] :: '[t8] :: '[t9] :: Nil =>
24+
Expr(9)
25+
case _ =>
26+
Expr(999)

0 commit comments

Comments
 (0)