Skip to content

Commit de795a9

Browse files
committed
Add caching to GADTMap
1 parent 4c41fc4 commit de795a9

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

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

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -720,14 +720,16 @@ object Contexts {
720720
final class SmartGADTMap private (
721721
private[this] var myConstraint: Constraint,
722722
private[this] var mapping: SimpleIdentityMap[Symbol, TypeVar],
723-
private[this] var reverseMapping: SimpleIdentityMap[TypeParamRef, Symbol]
723+
private[this] var reverseMapping: SimpleIdentityMap[TypeParamRef, Symbol],
724+
private[this] var boundCache: SimpleIdentityMap[Symbol, TypeBounds]
724725
) extends GADTMap with ConstraintHandling {
725726
import dotty.tools.dotc.config.Printers.{gadts, gadtsConstr}
726727

727728
def this() = this(
728729
myConstraint = new OrderingConstraint(SimpleIdentityMap.Empty, SimpleIdentityMap.Empty, SimpleIdentityMap.Empty),
729730
mapping = SimpleIdentityMap.Empty,
730-
reverseMapping = SimpleIdentityMap.Empty
731+
reverseMapping = SimpleIdentityMap.Empty,
732+
boundCache = SimpleIdentityMap.Empty
731733
)
732734

733735
// TODO: clean up this dirty kludge
@@ -748,7 +750,9 @@ object Contexts {
748750

749751
override def addEmptyBounds(sym: Symbol)(implicit ctx: Context): Unit = tvar(sym)
750752

751-
override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(implicit ctx: Context): Boolean = inCtx(ctx) {
753+
override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(implicit ctx: Context): Boolean = try { inCtx(ctx) {
754+
boundCache = SimpleIdentityMap.Empty
755+
boundAdditionInProgress = true
752756
@annotation.tailrec def stripInst(tp: Type): Type = tp match {
753757
case tv: TypeVar =>
754758
val inst = instType(tv)
@@ -807,14 +811,25 @@ object Contexts {
807811
i"adding $descr bound $sym $op $bound = $res\t( $symTvar $op $internalizedBound )"
808812
}
809813
res
810-
}
814+
}} finally boundAdditionInProgress = false
811815

812816
override def bounds(sym: Symbol)(implicit ctx: Context): TypeBounds = inCtx(ctx) {
813817
mapping(sym) match {
814818
case null => null
815819
case tv =>
816-
val tb = constraint.fullBounds(tv.origin)
817-
val res = removeTypeVars(tb).asInstanceOf[TypeBounds]
820+
def retrieveBounds: TypeBounds = {
821+
val tb = constraint.fullBounds(tv.origin)
822+
removeTypeVars(tb).asInstanceOf[TypeBounds]
823+
}
824+
val res =
825+
if (boundAdditionInProgress || ctx.mode.is(Mode.GADTflexible)) retrieveBounds
826+
else boundCache(sym) match {
827+
case tb: TypeBounds => tb
828+
case null =>
829+
val bounds = retrieveBounds
830+
boundCache = boundCache.updated(sym, bounds)
831+
bounds
832+
}
818833
// gadts.println(i"gadt bounds $sym: $res")
819834
res
820835
}
@@ -825,7 +840,8 @@ object Contexts {
825840
override def fresh: GADTMap = new SmartGADTMap(
826841
myConstraint,
827842
mapping,
828-
reverseMapping
843+
reverseMapping,
844+
boundCache
829845
)
830846

831847
// ---- Private ----------------------------------------------------------
@@ -882,6 +898,8 @@ object Contexts {
882898
override def apply(tp: Type): Type = removeTypeVars(tp, this)
883899
}
884900

901+
private[this] var boundAdditionInProgress = false
902+
885903
// ---- Debug ------------------------------------------------------------
886904

887905
override def constr_println(msg: => String): Unit = gadtsConstr.println(msg)

0 commit comments

Comments
 (0)