@@ -717,13 +717,23 @@ object Contexts {
717
717
def derived : GADTMap
718
718
}
719
719
720
- final class SmartGADTMap (
721
- private [this ] var myConstraint : Constraint = new OrderingConstraint (SimpleIdentityMap .Empty , SimpleIdentityMap .Empty , SimpleIdentityMap .Empty ),
722
- private [this ] var mapping : SimpleIdentityMap [Symbol , TypeVar ] = SimpleIdentityMap .Empty ,
723
- private [this ] var reverseMapping : SimpleIdentityMap [TypeParamRef , Symbol ] = SimpleIdentityMap .Empty
720
+ final class SmartGADTMap private (
721
+ private [this ] var myConstraint : Constraint ,
722
+ private [this ] var mapping : SimpleIdentityMap [Symbol , TypeVar ],
723
+ private [this ] var reverseMapping : SimpleIdentityMap [TypeParamRef , Symbol ],
724
+ private [this ] var boundCache : SimpleIdentityMap [Symbol , TypeBounds ],
725
+ private [this ] var dirtyFlag : Boolean
724
726
) extends GADTMap with ConstraintHandling {
725
727
import dotty .tools .dotc .config .Printers .gadts
726
728
729
+ def this () = this (
730
+ myConstraint = new OrderingConstraint (SimpleIdentityMap .Empty , SimpleIdentityMap .Empty , SimpleIdentityMap .Empty ),
731
+ mapping = SimpleIdentityMap .Empty ,
732
+ reverseMapping = SimpleIdentityMap .Empty ,
733
+ boundCache = SimpleIdentityMap .Empty ,
734
+ dirtyFlag = false
735
+ )
736
+
727
737
override def debugBoundsDescription (implicit ctx : Context ): String = {
728
738
val sb = new mutable.StringBuilder
729
739
sb ++= constraint.show
@@ -734,6 +744,8 @@ object Contexts {
734
744
sb.result
735
745
}
736
746
747
+ private [this ] var checkInProgress = false
748
+
737
749
// TODO: dirty kludge - should this class be an inner class of TyperState instead?
738
750
private [this ] var myCtx : Context = null
739
751
implicit override def ctx = myCtx
@@ -749,9 +761,10 @@ object Contexts {
749
761
override def isSubType (tp1 : Type , tp2 : Type ): Boolean = ctx.typeComparer.isSubType(tp1, tp2)
750
762
override def isSameType (tp1 : Type , tp2 : Type ): Boolean = ctx.typeComparer.isSameType(tp1, tp2)
751
763
752
- private [this ] def tvar (sym : Symbol )(implicit ctx : Context ): TypeVar = inCtx(ctx) {
753
- val res = mapping(sym) match {
754
- case tv : TypeVar => tv
764
+ private [this ] def tvar (sym : Symbol )(implicit ctx : Context ): TypeVar = {
765
+ mapping(sym) match {
766
+ case tv : TypeVar =>
767
+ tv
755
768
case null =>
756
769
val res = {
757
770
import NameKinds .DepParamName
@@ -769,12 +782,13 @@ object Contexts {
769
782
reverseMapping = reverseMapping.updated(res.origin, sym)
770
783
res
771
784
}
772
- res
773
785
}
774
786
775
787
override def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit = tvar(sym)
776
788
777
- override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = inCtx(ctx) {
789
+ override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = try inCtx(ctx) {
790
+ dirtyFlag = true
791
+ checkInProgress = true
778
792
@ annotation.tailrec def stripInst (tp : Type ): Type = tp match {
779
793
case tv : TypeVar =>
780
794
val inst = instType(tv)
@@ -795,8 +809,8 @@ object Contexts {
795
809
796
810
val outerCtx = ctx
797
811
val res = {
798
- implicit val ctx : Context =
799
- if (allowNarrowing) outerCtx else outerCtx.fresh.retractMode(Mode .GADTflexible )
812
+ // implicit val ctx : Context =
813
+ // if (allowNarrowing) outerCtx else outerCtx.fresh.retractMode(Mode.GADTflexible)
800
814
801
815
// TypeComparer.explain[Boolean](gadts.println) { implicit ctx =>
802
816
if (isSubtype) externalizedTp1 frozen_<:< externalizedTp2
@@ -811,6 +825,7 @@ object Contexts {
811
825
case tv : TypeVar => tv
812
826
case inst =>
813
827
gadts.println(i " instantiated: $sym -> $inst" )
828
+ // return true
814
829
return cautiousSubtype(inst, bound, isSubtype = isUpper, allowNarrowing = true )
815
830
}
816
831
@@ -847,25 +862,47 @@ object Contexts {
847
862
i " adding $descr bound $sym $op $bound = $res\t ( $symTvar $op $tvarBound ) "
848
863
}
849
864
res
850
- }
865
+ } finally checkInProgress = false
851
866
852
867
override def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = inCtx(ctx) {
853
868
mapping(sym) match {
854
869
case null => null
855
870
case tv =>
856
- val tb = constraint.fullBounds(tv.origin)
857
- val res = (new TypeVarRemovingMap )(tb).asInstanceOf [TypeBounds ]
858
- // gadts.println(i"gadt bounds $sym: $res\t( $tv: $tb )")
871
+ def retrieveBounds : TypeBounds = {
872
+ val tb = constraint.fullBounds(tv.origin)
873
+ (new TypeVarRemovingMap )(tb).asInstanceOf [TypeBounds ]
874
+ }
875
+ val res =
876
+ // retrieveBounds
877
+ if (checkInProgress || ctx.mode.is(Mode .GADTflexible )) retrieveBounds
878
+ else {
879
+ if (dirtyFlag) {
880
+ dirtyFlag = false
881
+ val bounds = retrieveBounds
882
+ boundCache = SimpleIdentityMap .Empty .updated(sym, bounds)
883
+ bounds
884
+ } else boundCache(sym) match {
885
+ case tb : TypeBounds =>
886
+ tb
887
+ case null =>
888
+ val bounds = retrieveBounds
889
+ boundCache = boundCache.updated(sym, bounds)
890
+ bounds
891
+ }
892
+ }
893
+ // gadts.println(i"gadt bounds $sym: $res")
859
894
res
860
895
}
861
896
}
862
897
863
898
override def contains (sym : Symbol )(implicit ctx : Context ): Boolean = mapping(sym) ne null
864
899
865
900
override def derived : GADTMap = new SmartGADTMap (
866
- this .myConstraint,
867
- this .mapping,
868
- this .reverseMapping
901
+ myConstraint,
902
+ mapping,
903
+ reverseMapping,
904
+ boundCache,
905
+ dirtyFlag
869
906
)
870
907
871
908
private final class TypeVarInsertingMap extends TypeMap {
0 commit comments