@@ -139,9 +139,9 @@ object Contexts {
139
139
final def importInfo : ImportInfo = _importInfo
140
140
141
141
/** The current bounds in force for type parameters appearing in a GADT */
142
- private [this ] var _gadt : GADTMap = _
143
- protected def gadt_= (gadt : GADTMap ): Unit = _gadt = gadt
144
- final def gadt : GADTMap = _gadt
142
+ private [this ] var _gadt : GadtConstraint = _
143
+ protected def gadt_= (gadt : GadtConstraint ): Unit = _gadt = gadt
144
+ final def gadt : GadtConstraint = _gadt
145
145
146
146
/** The history of implicit searches that are currently active */
147
147
private [this ] var _searchHistory : SearchHistory = null
@@ -534,7 +534,7 @@ object Contexts {
534
534
def setTypeAssigner (typeAssigner : TypeAssigner ): this .type = { this .typeAssigner = typeAssigner; this }
535
535
def setTyper (typer : Typer ): this .type = { this .scope = typer.scope; setTypeAssigner(typer) }
536
536
def setImportInfo (importInfo : ImportInfo ): this .type = { this .importInfo = importInfo; this }
537
- def setGadt (gadt : GADTMap ): this .type = { this .gadt = gadt; this }
537
+ def setGadt (gadt : GadtConstraint ): this .type = { this .gadt = gadt; this }
538
538
def setFreshGADTBounds : this .type = setGadt(gadt.fresh)
539
539
def setSearchHistory (searchHistory : SearchHistory ): this .type = { this .searchHistory = searchHistory; this }
540
540
def setSource (source : SourceFile ): this .type = { this .source = source; this }
@@ -617,7 +617,7 @@ object Contexts {
617
617
store = initialStore.updated(settingsStateLoc, settingsGroup.defaultState)
618
618
typeComparer = new TypeComparer (this )
619
619
searchHistory = new SearchRoot
620
- gadt = EmptyGADTMap
620
+ gadt = EmptyGadtConstraint
621
621
}
622
622
623
623
@ sharable object NoContext extends Context (null ) {
@@ -774,233 +774,4 @@ object Contexts {
774
774
if (thread == null ) thread = Thread .currentThread()
775
775
else assert(thread == Thread .currentThread(), " illegal multithreaded access to ContextBase" )
776
776
}
777
-
778
- sealed abstract class GADTMap {
779
- def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit
780
- def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean
781
- def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds
782
- def contains (sym : Symbol )(implicit ctx : Context ): Boolean
783
- def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type
784
- def debugBoundsDescription (implicit ctx : Context ): String
785
- def fresh : GADTMap
786
- def restore (other : GADTMap ): Unit
787
- def isEmpty : Boolean
788
- }
789
-
790
- final class SmartGADTMap private (
791
- private var myConstraint : Constraint ,
792
- private var mapping : SimpleIdentityMap [Symbol , TypeVar ],
793
- private var reverseMapping : SimpleIdentityMap [TypeParamRef , Symbol ],
794
- private var boundCache : SimpleIdentityMap [Symbol , TypeBounds ]
795
- ) extends GADTMap with ConstraintHandling [Context ] {
796
- import dotty .tools .dotc .config .Printers .{gadts , gadtsConstr }
797
-
798
- def this () = this (
799
- myConstraint = new OrderingConstraint (SimpleIdentityMap .Empty , SimpleIdentityMap .Empty , SimpleIdentityMap .Empty ),
800
- mapping = SimpleIdentityMap .Empty ,
801
- reverseMapping = SimpleIdentityMap .Empty ,
802
- boundCache = SimpleIdentityMap .Empty
803
- )
804
-
805
- implicit override def ctx (implicit ctx : Context ): Context = ctx
806
-
807
- override protected def constraint = myConstraint
808
- override protected def constraint_= (c : Constraint ) = myConstraint = c
809
-
810
- override def isSubType (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Boolean = ctx.typeComparer.isSubType(tp1, tp2)
811
- override def isSameType (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Boolean = ctx.typeComparer.isSameType(tp1, tp2)
812
-
813
- override def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit = tvar(sym)
814
-
815
- override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = try {
816
- boundCache = SimpleIdentityMap .Empty
817
- boundAdditionInProgress = true
818
- @ annotation.tailrec def stripInternalTypeVar (tp : Type ): Type = tp match {
819
- case tv : TypeVar =>
820
- val inst = instType(tv)
821
- if (inst.exists) stripInternalTypeVar(inst) else tv
822
- case _ => tp
823
- }
824
-
825
- def externalizedSubtype (tp1 : Type , tp2 : Type , isSubtype : Boolean ): Boolean = {
826
- val externalizedTp1 = removeTypeVars(tp1)
827
- val externalizedTp2 = removeTypeVars(tp2)
828
-
829
- (
830
- if (isSubtype) externalizedTp1 frozen_<:< externalizedTp2
831
- else externalizedTp2 frozen_<:< externalizedTp1
832
- ).reporting({ res =>
833
- val descr = i " $externalizedTp1 frozen_ ${if (isSubtype) " <:<" else " >:>" } $externalizedTp2"
834
- i " $descr = $res"
835
- }, gadts)
836
- }
837
-
838
- val symTvar : TypeVar = stripInternalTypeVar(tvar(sym)) match {
839
- case tv : TypeVar => tv
840
- case inst =>
841
- val externalizedInst = removeTypeVars(inst)
842
- gadts.println(i " instantiated: $sym -> $externalizedInst" )
843
- return if (isUpper) isSubType(externalizedInst , bound) else isSubType(bound, externalizedInst)
844
- }
845
-
846
- val internalizedBound = insertTypeVars(bound)
847
- (
848
- stripInternalTypeVar(internalizedBound) match {
849
- case boundTvar : TypeVar =>
850
- if (boundTvar eq symTvar) true
851
- else if (isUpper) addLess(symTvar.origin, boundTvar.origin)
852
- else addLess(boundTvar.origin, symTvar.origin)
853
- case bound =>
854
- if (externalizedSubtype(symTvar, bound, isSubtype = ! isUpper)) {
855
- gadts.println(i " manually unifying $symTvar with $bound" )
856
- constraint = constraint.updateEntry(symTvar.origin, bound)
857
- true
858
- }
859
- else if (isUpper) addUpperBound(symTvar.origin, bound)
860
- else addLowerBound(symTvar.origin, bound)
861
- }
862
- ).reporting({ res =>
863
- val descr = if (isUpper) " upper" else " lower"
864
- val op = if (isUpper) " <:" else " >:"
865
- i " adding $descr bound $sym $op $bound = $res\t ( $symTvar $op $internalizedBound ) "
866
- }, gadts)
867
- } finally boundAdditionInProgress = false
868
-
869
- override def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = {
870
- mapping(sym) match {
871
- case null => null
872
- case tv =>
873
- def retrieveBounds : TypeBounds = {
874
- val tb = constraint.fullBounds(tv.origin)
875
- removeTypeVars(tb).asInstanceOf [TypeBounds ]
876
- }
877
- (
878
- if (boundAdditionInProgress || ctx.mode.is(Mode .GADTflexible )) retrieveBounds
879
- else boundCache(sym) match {
880
- case tb : TypeBounds => tb
881
- case null =>
882
- val bounds = retrieveBounds
883
- boundCache = boundCache.updated(sym, bounds)
884
- bounds
885
- }
886
- ).reporting({ res =>
887
- // i"gadt bounds $sym: $res"
888
- " "
889
- }, gadts)
890
- }
891
- }
892
-
893
- override def contains (sym : Symbol )(implicit ctx : Context ): Boolean = mapping(sym) ne null
894
-
895
- override def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type = {
896
- val res = removeTypeVars(approximation(tvar(sym).origin, fromBelow = fromBelow))
897
- gadts.println(i " approximating $sym ~> $res" )
898
- res
899
- }
900
-
901
- override def fresh : GADTMap = new SmartGADTMap (
902
- myConstraint,
903
- mapping,
904
- reverseMapping,
905
- boundCache
906
- )
907
-
908
- def restore (other : GADTMap ): Unit = other match {
909
- case other : SmartGADTMap =>
910
- this .myConstraint = other.myConstraint
911
- this .mapping = other.mapping
912
- this .reverseMapping = other.reverseMapping
913
- this .boundCache = other.boundCache
914
- case _ => ;
915
- }
916
-
917
- override def isEmpty : Boolean = mapping.size == 0
918
-
919
- // ---- Private ----------------------------------------------------------
920
-
921
- private [this ] def tvar (sym : Symbol )(implicit ctx : Context ): TypeVar = {
922
- mapping(sym) match {
923
- case tv : TypeVar =>
924
- tv
925
- case null =>
926
- val res = {
927
- import NameKinds .DepParamName
928
- // avoid registering the TypeVar with TyperState / TyperState#constraint
929
- // - we don't want TyperState instantiating these TypeVars
930
- // - we don't want TypeComparer constraining these TypeVars
931
- val poly = PolyType (DepParamName .fresh(sym.name.toTypeName) :: Nil )(
932
- pt => (sym.info match {
933
- case tb @ TypeBounds (_, hi) if hi.isLambdaSub => tb
934
- case _ => TypeBounds .empty
935
- }) :: Nil ,
936
- pt => defn.AnyType )
937
- new TypeVar (poly.paramRefs.head, creatorState = null )
938
- }
939
- gadts.println(i " GADTMap: created tvar $sym -> $res" )
940
- constraint = constraint.add(res.origin.binder, res :: Nil )
941
- mapping = mapping.updated(sym, res)
942
- reverseMapping = reverseMapping.updated(res.origin, sym)
943
- res
944
- }
945
- }
946
-
947
- private def insertTypeVars (tp : Type , map : TypeMap = null )(implicit ctx : Context ) = tp match {
948
- case tp : TypeRef =>
949
- val sym = tp.typeSymbol
950
- if (contains(sym)) tvar(sym) else tp
951
- case _ =>
952
- (if (map != null ) map else new TypeVarInsertingMap ()).mapOver(tp)
953
- }
954
- private final class TypeVarInsertingMap (implicit ctx : Context ) extends TypeMap {
955
- override def apply (tp : Type ): Type = insertTypeVars(tp, this )
956
- }
957
-
958
- private def removeTypeVars (tp : Type , map : TypeMap = null )(implicit ctx : Context ) = tp match {
959
- case tpr : TypeParamRef =>
960
- reverseMapping(tpr) match {
961
- case null => tpr
962
- case sym => sym.typeRef
963
- }
964
- case tv : TypeVar =>
965
- reverseMapping(tv.origin) match {
966
- case null => tv
967
- case sym => sym.typeRef
968
- }
969
- case _ =>
970
- (if (map != null ) map else new TypeVarRemovingMap ()).mapOver(tp)
971
- }
972
- private final class TypeVarRemovingMap (implicit ctx : Context ) extends TypeMap {
973
- override def apply (tp : Type ): Type = removeTypeVars(tp, this )
974
- }
975
-
976
- private [this ] var boundAdditionInProgress = false
977
-
978
- // ---- Debug ------------------------------------------------------------
979
-
980
- override def constr_println (msg : => String ): Unit = gadtsConstr.println(msg)
981
-
982
- override def debugBoundsDescription (implicit ctx : Context ): String = {
983
- val sb = new mutable.StringBuilder
984
- sb ++= constraint.show
985
- sb += '\n '
986
- mapping.foreachBinding { case (sym, _) =>
987
- sb ++= i " $sym: ${bounds(sym)}\n "
988
- }
989
- sb.result
990
- }
991
- }
992
-
993
- @ sharable object EmptyGADTMap extends GADTMap {
994
- override def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit = unsupported(" EmptyGADTMap.addEmptyBounds" )
995
- override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = unsupported(" EmptyGADTMap.addBound" )
996
- override def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = null
997
- override def contains (sym : Symbol )(implicit ctx : Context ) = false
998
- override def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type = unsupported(" EmptyGADTMap.approximation" )
999
- override def debugBoundsDescription (implicit ctx : Context ): String = " EmptyGADTMap"
1000
- override def fresh = new SmartGADTMap
1001
- override def restore (other : GADTMap ): Unit = {
1002
- if (! other.isEmpty) sys.error(" cannot restore a non-empty GADTMap" )
1003
- }
1004
- override def isEmpty : Boolean = true
1005
- }
1006
777
}
0 commit comments