Skip to content

Commit 3d71367

Browse files
committed
Clean up TypeVar insertion/removal in SmartGADTMap
If we do not insert TypeVars into the bounds every time, then the only time we need to remove them is when taking the full bounds of some type. Since that logic now resides in ConstraintHandling and replaces all TypeParamRefs internal to SmartGADTMap, we have no need to perform expensive type traversals. This removes the only reason for caching bounds.
1 parent cf63a38 commit 3d71367

File tree

1 file changed

+21
-80
lines changed

1 file changed

+21
-80
lines changed

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

Lines changed: 21 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -780,15 +780,13 @@ object Contexts {
780780
private var myConstraint: Constraint,
781781
private var mapping: SimpleIdentityMap[Symbol, TypeVar],
782782
private var reverseMapping: SimpleIdentityMap[TypeParamRef, Symbol],
783-
private var boundCache: SimpleIdentityMap[Symbol, TypeBounds]
784783
) extends GADTMap with ConstraintHandling[Context] {
785784
import dotty.tools.dotc.config.Printers.{gadts, gadtsConstr}
786785

787786
def this() = this(
788787
myConstraint = new OrderingConstraint(SimpleIdentityMap.Empty, SimpleIdentityMap.Empty, SimpleIdentityMap.Empty),
789788
mapping = SimpleIdentityMap.Empty,
790-
reverseMapping = SimpleIdentityMap.Empty,
791-
boundCache = SimpleIdentityMap.Empty
789+
reverseMapping = SimpleIdentityMap.Empty
792790
)
793791

794792
implicit override def ctx(implicit ctx: Context): Context = ctx
@@ -807,111 +805,85 @@ object Contexts {
807805

808806
override def addEmptyBounds(sym: Symbol)(implicit ctx: Context): Unit = tvar(sym)
809807

810-
override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(implicit ctx: Context): Boolean = try {
811-
boundCache = SimpleIdentityMap.Empty
812-
boundAdditionInProgress = true
808+
override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(implicit ctx: Context): Boolean = {
813809
@annotation.tailrec def stripInternalTypeVar(tp: Type): Type = tp match {
814810
case tv: TypeVar =>
815811
val inst = instType(tv)
816812
if (inst.exists) stripInternalTypeVar(inst) else tv
817813
case _ => tp
818814
}
819815

820-
def externalizedSubtype(tp1: Type, tp2: Type, isSubtype: Boolean): Boolean = {
821-
val externalizedTp1 = removeTypeVars(tp1)
822-
val externalizedTp2 = removeTypeVars(tp2)
823-
824-
(
825-
if (isSubtype) externalizedTp1 frozen_<:< externalizedTp2
826-
else externalizedTp2 frozen_<:< externalizedTp1
827-
).reporting({ res =>
828-
val descr = i"$externalizedTp1 frozen_${if (isSubtype) "<:<" else ">:>"} $externalizedTp2"
829-
i"$descr = $res"
830-
}, gadts)
831-
}
832-
833816
val symTvar: TypeVar = stripInternalTypeVar(tvar(sym)) match {
834817
case tv: TypeVar => tv
835818
case inst =>
836-
val externalizedInst = removeTypeVars(inst)
837-
gadts.println(i"instantiated: $sym -> $externalizedInst")
838-
return if (isUpper) isSubType(externalizedInst , bound) else isSubType(bound, externalizedInst)
819+
gadts.println(i"instantiated: $sym -> $inst")
820+
return if (isUpper) isSubType(inst , bound) else isSubType(bound, inst)
839821
}
840822

841-
val internalizedBound = insertTypeVars(bound)
823+
val internalizedBound = bound match {
824+
case nt: NamedType if contains(nt.symbol) =>
825+
stripInternalTypeVar(tvar(nt.symbol))
826+
case _ => bound
827+
}
842828
(
843-
stripInternalTypeVar(internalizedBound) match {
829+
internalizedBound match {
844830
case boundTvar: TypeVar =>
845831
if (boundTvar eq symTvar) true
846832
else if (isUpper) addLess(symTvar.origin, boundTvar.origin)
847833
else addLess(boundTvar.origin, symTvar.origin)
848834
case bound =>
849-
if (externalizedSubtype(symTvar, bound, isSubtype = !isUpper)) {
850-
gadts.println(i"manually unifying $symTvar with $bound")
851-
constraint = constraint.updateEntry(symTvar.origin, bound)
852-
true
853-
}
854-
else if (isUpper) addUpperBound(symTvar.origin, bound)
835+
if (isUpper) addUpperBound(symTvar.origin, bound)
855836
else addLowerBound(symTvar.origin, bound)
856837
}
857838
).reporting({ res =>
858839
val descr = if (isUpper) "upper" else "lower"
859840
val op = if (isUpper) "<:" else ">:"
860841
i"adding $descr bound $sym $op $bound = $res\t( $symTvar $op $internalizedBound )"
861842
}, gadts)
862-
} finally boundAdditionInProgress = false
843+
}
863844

864845
override def isLess(sym1: Symbol, sym2: Symbol)(implicit ctx: Context): Boolean =
865846
constraint.isLess(tvar(sym1).origin, tvar(sym2).origin)
866847

867848
override def fullBounds(sym: Symbol)(implicit ctx: Context): TypeBounds =
868849
mapping(sym) match {
869850
case null => null
870-
case tv => removeTypeVars(fullBounds(tv.origin)).asInstanceOf[TypeBounds]
851+
case tv => fullBounds(tv.origin)
871852
}
872853

873854
override def bounds(sym: Symbol)(implicit ctx: Context): TypeBounds = {
874855
mapping(sym) match {
875856
case null => null
876857
case tv =>
877-
def retrieveBounds: TypeBounds = {
878-
val tb = bounds(tv.origin)
879-
removeTypeVars(tb).asInstanceOf[TypeBounds]
880-
}
881-
(
882-
if (boundAdditionInProgress || ctx.mode.is(Mode.GADTflexible)) retrieveBounds
883-
else boundCache(sym) match {
884-
case tb: TypeBounds => tb
885-
case null =>
886-
val bounds = retrieveBounds
887-
boundCache = boundCache.updated(sym, bounds)
888-
bounds
858+
def retrieveBounds: TypeBounds =
859+
bounds(tv.origin) match {
860+
case TypeAlias(tpr: TypeParamRef) if reverseMapping.contains(tpr) =>
861+
TypeAlias(reverseMapping(tpr).typeRef)
862+
case tb => tb
889863
}
890-
)// .reporting({ res => i"gadt bounds $sym: $res" }, gadts)
864+
retrieveBounds//.reporting({ res => i"gadt bounds $sym: $res" }, gadts)
891865
}
892866
}
893867

894868
override def contains(sym: Symbol)(implicit ctx: Context): Boolean = mapping(sym) ne null
895869

896870
override def approximation(sym: Symbol, fromBelow: Boolean)(implicit ctx: Context): Type = {
897-
val res = removeTypeVars(approximation(tvar(sym).origin, fromBelow = fromBelow))
871+
val res = approximation(tvar(sym).origin, fromBelow = fromBelow)
898872
gadts.println(i"approximating $sym ~> $res")
899873
res
900874
}
901875

902876
override def fresh: GADTMap = new SmartGADTMap(
903877
myConstraint,
904878
mapping,
905-
reverseMapping,
906-
boundCache
879+
reverseMapping
907880
)
908881

909882
def restore(other: GADTMap): Unit = other match {
910883
case other: SmartGADTMap =>
911884
this.myConstraint = other.myConstraint
912885
this.mapping = other.mapping
913886
this.reverseMapping = other.reverseMapping
914-
this.boundCache = other.boundCache
915887
case _ => ;
916888
}
917889

@@ -942,37 +914,6 @@ object Contexts {
942914
}
943915
}
944916

945-
private def insertTypeVars(tp: Type, map: TypeMap = null)(implicit ctx: Context) = tp match {
946-
case tp: TypeRef =>
947-
val sym = tp.typeSymbol
948-
if (contains(sym)) tvar(sym) else tp
949-
case _ =>
950-
(if (map != null) map else new TypeVarInsertingMap()).mapOver(tp)
951-
}
952-
private final class TypeVarInsertingMap(implicit ctx: Context) extends TypeMap {
953-
override def apply(tp: Type): Type = insertTypeVars(tp, this)
954-
}
955-
956-
private def removeTypeVars(tp: Type, map: TypeMap = null)(implicit ctx: Context) = tp match {
957-
case tpr: TypeParamRef =>
958-
reverseMapping(tpr) match {
959-
case null => tpr
960-
case sym => sym.typeRef
961-
}
962-
case tv: TypeVar =>
963-
reverseMapping(tv.origin) match {
964-
case null => tv
965-
case sym => sym.typeRef
966-
}
967-
case _ =>
968-
(if (map != null) map else new TypeVarRemovingMap()).mapOver(tp)
969-
}
970-
private final class TypeVarRemovingMap(implicit ctx: Context) extends TypeMap {
971-
override def apply(tp: Type): Type = removeTypeVars(tp, this)
972-
}
973-
974-
private[this] var boundAdditionInProgress = false
975-
976917
// ---- Debug ------------------------------------------------------------
977918

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

0 commit comments

Comments
 (0)