Skip to content

Commit 3fe9ef9

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 649a9e4 commit 3fe9ef9

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
@@ -786,15 +786,13 @@ object Contexts {
786786
private var myConstraint: Constraint,
787787
private var mapping: SimpleIdentityMap[Symbol, TypeVar],
788788
private var reverseMapping: SimpleIdentityMap[TypeParamRef, Symbol],
789-
private var boundCache: SimpleIdentityMap[Symbol, TypeBounds]
790789
) extends GADTMap with ConstraintHandling[Context] {
791790
import dotty.tools.dotc.config.Printers.{gadts, gadtsConstr}
792791

793792
def this() = this(
794793
myConstraint = new OrderingConstraint(SimpleIdentityMap.Empty, SimpleIdentityMap.Empty, SimpleIdentityMap.Empty),
795794
mapping = SimpleIdentityMap.Empty,
796-
reverseMapping = SimpleIdentityMap.Empty,
797-
boundCache = SimpleIdentityMap.Empty
795+
reverseMapping = SimpleIdentityMap.Empty
798796
)
799797

800798
implicit override def ctx(implicit ctx: Context): Context = ctx
@@ -813,111 +811,85 @@ object Contexts {
813811

814812
override def addEmptyBounds(sym: Symbol)(implicit ctx: Context): Unit = tvar(sym)
815813

816-
override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(implicit ctx: Context): Boolean = try {
817-
boundCache = SimpleIdentityMap.Empty
818-
boundAdditionInProgress = true
814+
override def addBound(sym: Symbol, bound: Type, isUpper: Boolean)(implicit ctx: Context): Boolean = {
819815
@annotation.tailrec def stripInternalTypeVar(tp: Type): Type = tp match {
820816
case tv: TypeVar =>
821817
val inst = instType(tv)
822818
if (inst.exists) stripInternalTypeVar(inst) else tv
823819
case _ => tp
824820
}
825821

826-
def externalizedSubtype(tp1: Type, tp2: Type, isSubtype: Boolean): Boolean = {
827-
val externalizedTp1 = removeTypeVars(tp1)
828-
val externalizedTp2 = removeTypeVars(tp2)
829-
830-
(
831-
if (isSubtype) externalizedTp1 frozen_<:< externalizedTp2
832-
else externalizedTp2 frozen_<:< externalizedTp1
833-
).reporting({ res =>
834-
val descr = i"$externalizedTp1 frozen_${if (isSubtype) "<:<" else ">:>"} $externalizedTp2"
835-
i"$descr = $res"
836-
}, gadts)
837-
}
838-
839822
val symTvar: TypeVar = stripInternalTypeVar(tvar(sym)) match {
840823
case tv: TypeVar => tv
841824
case inst =>
842-
val externalizedInst = removeTypeVars(inst)
843-
gadts.println(i"instantiated: $sym -> $externalizedInst")
844-
return if (isUpper) isSubType(externalizedInst , bound) else isSubType(bound, externalizedInst)
825+
gadts.println(i"instantiated: $sym -> $inst")
826+
return if (isUpper) isSubType(inst , bound) else isSubType(bound, inst)
845827
}
846828

847-
val internalizedBound = insertTypeVars(bound)
829+
val internalizedBound = bound match {
830+
case nt: NamedType if contains(nt.symbol) =>
831+
stripInternalTypeVar(tvar(nt.symbol))
832+
case _ => bound
833+
}
848834
(
849-
stripInternalTypeVar(internalizedBound) match {
835+
internalizedBound match {
850836
case boundTvar: TypeVar =>
851837
if (boundTvar eq symTvar) true
852838
else if (isUpper) addLess(symTvar.origin, boundTvar.origin)
853839
else addLess(boundTvar.origin, symTvar.origin)
854840
case bound =>
855-
if (externalizedSubtype(symTvar, bound, isSubtype = !isUpper)) {
856-
gadts.println(i"manually unifying $symTvar with $bound")
857-
constraint = constraint.updateEntry(symTvar.origin, bound)
858-
true
859-
}
860-
else if (isUpper) addUpperBound(symTvar.origin, bound)
841+
if (isUpper) addUpperBound(symTvar.origin, bound)
861842
else addLowerBound(symTvar.origin, bound)
862843
}
863844
).reporting({ res =>
864845
val descr = if (isUpper) "upper" else "lower"
865846
val op = if (isUpper) "<:" else ">:"
866847
i"adding $descr bound $sym $op $bound = $res\t( $symTvar $op $internalizedBound )"
867848
}, gadts)
868-
} finally boundAdditionInProgress = false
849+
}
869850

870851
override def isLess(sym1: Symbol, sym2: Symbol)(implicit ctx: Context): Boolean =
871852
constraint.isLess(tvar(sym1).origin, tvar(sym2).origin)
872853

873854
override def fullBounds(sym: Symbol)(implicit ctx: Context): TypeBounds =
874855
mapping(sym) match {
875856
case null => null
876-
case tv => removeTypeVars(fullBounds(tv.origin)).asInstanceOf[TypeBounds]
857+
case tv => fullBounds(tv.origin)
877858
}
878859

879860
override def bounds(sym: Symbol)(implicit ctx: Context): TypeBounds = {
880861
mapping(sym) match {
881862
case null => null
882863
case tv =>
883-
def retrieveBounds: TypeBounds = {
884-
val tb = bounds(tv.origin)
885-
removeTypeVars(tb).asInstanceOf[TypeBounds]
886-
}
887-
(
888-
if (boundAdditionInProgress || ctx.mode.is(Mode.GADTflexible)) retrieveBounds
889-
else boundCache(sym) match {
890-
case tb: TypeBounds => tb
891-
case null =>
892-
val bounds = retrieveBounds
893-
boundCache = boundCache.updated(sym, bounds)
894-
bounds
864+
def retrieveBounds: TypeBounds =
865+
bounds(tv.origin) match {
866+
case TypeAlias(tpr: TypeParamRef) if reverseMapping.contains(tpr) =>
867+
TypeAlias(reverseMapping(tpr).typeRef)
868+
case tb => tb
895869
}
896-
)// .reporting({ res => i"gadt bounds $sym: $res" }, gadts)
870+
retrieveBounds//.reporting({ res => i"gadt bounds $sym: $res" }, gadts)
897871
}
898872
}
899873

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

902876
override def approximation(sym: Symbol, fromBelow: Boolean)(implicit ctx: Context): Type = {
903-
val res = removeTypeVars(approximation(tvar(sym).origin, fromBelow = fromBelow))
877+
val res = approximation(tvar(sym).origin, fromBelow = fromBelow)
904878
gadts.println(i"approximating $sym ~> $res")
905879
res
906880
}
907881

908882
override def fresh: GADTMap = new SmartGADTMap(
909883
myConstraint,
910884
mapping,
911-
reverseMapping,
912-
boundCache
885+
reverseMapping
913886
)
914887

915888
def restore(other: GADTMap): Unit = other match {
916889
case other: SmartGADTMap =>
917890
this.myConstraint = other.myConstraint
918891
this.mapping = other.mapping
919892
this.reverseMapping = other.reverseMapping
920-
this.boundCache = other.boundCache
921893
case _ => ;
922894
}
923895

@@ -948,37 +920,6 @@ object Contexts {
948920
}
949921
}
950922

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

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

0 commit comments

Comments
 (0)