@@ -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,221 +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 extends Showable {
779
- def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit
780
- def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean
781
- def isLess (sym1 : Symbol , sym2 : Symbol )(implicit ctx : Context ): Boolean
782
- def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds
783
-
784
- /** Full bounds of `sym`, including TypeRefs to other lower/upper symbols.
785
- *
786
- * Note that underlying operations perform subtype checks - for this reason, recursing on `fullBounds`
787
- * of some symbol when comparing types might lead to infinite recursion. Consider `bounds` instead.
788
- */
789
- def fullBounds (sym : Symbol )(implicit ctx : Context ): TypeBounds
790
- def contains (sym : Symbol )(implicit ctx : Context ): Boolean
791
- def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type
792
- def debugBoundsDescription (implicit ctx : Context ): String
793
- def fresh : GADTMap
794
- def restore (other : GADTMap ): Unit
795
- def isEmpty : Boolean
796
- }
797
-
798
- final class SmartGADTMap private (
799
- private var myConstraint : Constraint ,
800
- private var mapping : SimpleIdentityMap [Symbol , TypeVar ],
801
- private var reverseMapping : SimpleIdentityMap [TypeParamRef , Symbol ],
802
- ) extends GADTMap with ConstraintHandling [Context ] {
803
- import dotty .tools .dotc .config .Printers .{gadts , gadtsConstr }
804
-
805
- def subsumes (left : GADTMap , right : GADTMap , pre : GADTMap )(implicit ctx : Context ): Boolean = {
806
- def extractConstraint (g : GADTMap ) = g match {
807
- case s : SmartGADTMap => s.constraint
808
- case EmptyGADTMap => OrderingConstraint .empty
809
- }
810
- subsumes(extractConstraint(left), extractConstraint(right), extractConstraint(pre))
811
- }
812
-
813
- def this () = this (
814
- myConstraint = new OrderingConstraint (SimpleIdentityMap .Empty , SimpleIdentityMap .Empty , SimpleIdentityMap .Empty ),
815
- mapping = SimpleIdentityMap .Empty ,
816
- reverseMapping = SimpleIdentityMap .Empty
817
- )
818
-
819
- implicit override def ctx (implicit ctx : Context ): Context = ctx
820
-
821
- override protected def constraint = myConstraint
822
- override protected def constraint_= (c : Constraint ) = myConstraint = c
823
-
824
- override protected def externalize (param : TypeParamRef )(implicit ctx : Context ): Type =
825
- reverseMapping(param) match {
826
- case sym : Symbol => sym.typeRef
827
- case null => param
828
- }
829
-
830
- override def isSubType (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Boolean = ctx.typeComparer.isSubType(tp1, tp2)
831
- override def isSameType (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Boolean = ctx.typeComparer.isSameType(tp1, tp2)
832
-
833
- override protected def typeLub (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Type = {
834
- ctx.typeComparer.lub(tp1, tp2, admitSingletons = true )
835
- }
836
-
837
- override def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit = tvar(sym)
838
-
839
- override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = {
840
- @ annotation.tailrec def stripInternalTypeVar (tp : Type ): Type = tp match {
841
- case tv : TypeVar =>
842
- val inst = instType(tv)
843
- if (inst.exists) stripInternalTypeVar(inst) else tv
844
- case _ => tp
845
- }
846
-
847
- val symTvar : TypeVar = stripInternalTypeVar(tvar(sym)) match {
848
- case tv : TypeVar => tv
849
- case inst =>
850
- gadts.println(i " instantiated: $sym -> $inst" )
851
- return if (isUpper) isSubType(inst , bound) else isSubType(bound, inst)
852
- }
853
-
854
- val internalizedBound = bound match {
855
- case nt : NamedType if contains(nt.symbol) =>
856
- stripInternalTypeVar(tvar(nt.symbol))
857
- case _ => bound
858
- }
859
- (
860
- internalizedBound match {
861
- case boundTvar : TypeVar =>
862
- if (boundTvar eq symTvar) true
863
- else if (isUpper) addLess(symTvar.origin, boundTvar.origin)
864
- else addLess(boundTvar.origin, symTvar.origin)
865
- case bound =>
866
- val oldUpperBound = bounds(symTvar.origin)
867
- // If we already have bounds `F >: [t] => List[t] <: [t] => Any`
868
- // and we want to record that `F <: [+A] => List[A]`, we need to adapt
869
- // type parameter variances of the bound. Consider that the following is valid:
870
- //
871
- // class Foo[F[t] >: List[t]]
872
- // type T = Foo[List]
873
- //
874
- // precisely because `Foo[List]` is desugared to `Foo[[A] => List[A]]`.
875
- val bound1 = bound.adaptHkVariances(oldUpperBound)
876
- if (isUpper) addUpperBound(symTvar.origin, bound1)
877
- else addLowerBound(symTvar.origin, bound1)
878
- }
879
- ).reporting({ res =>
880
- val descr = if (isUpper) " upper" else " lower"
881
- val op = if (isUpper) " <:" else " >:"
882
- i " adding $descr bound $sym $op $bound = $res\t ( $symTvar $op $internalizedBound ) "
883
- }, gadts)
884
- }
885
-
886
- override def isLess (sym1 : Symbol , sym2 : Symbol )(implicit ctx : Context ): Boolean =
887
- constraint.isLess(tvar(sym1).origin, tvar(sym2).origin)
888
-
889
- override def fullBounds (sym : Symbol )(implicit ctx : Context ): TypeBounds =
890
- mapping(sym) match {
891
- case null => null
892
- case tv => fullBounds(tv.origin)
893
- }
894
-
895
- override def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = {
896
- mapping(sym) match {
897
- case null => null
898
- case tv =>
899
- def retrieveBounds : TypeBounds =
900
- bounds(tv.origin) match {
901
- case TypeAlias (tpr : TypeParamRef ) if reverseMapping.contains(tpr) =>
902
- TypeAlias (reverseMapping(tpr).typeRef)
903
- case tb => tb
904
- }
905
- retrieveBounds// .reporting({ res => i"gadt bounds $sym: $res" }, gadts)
906
- }
907
- }
908
-
909
- override def contains (sym : Symbol )(implicit ctx : Context ): Boolean = mapping(sym) ne null
910
-
911
- override def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type = {
912
- val res = approximation(tvar(sym).origin, fromBelow = fromBelow)
913
- gadts.println(i " approximating $sym ~> $res" )
914
- res
915
- }
916
-
917
- override def fresh : GADTMap = new SmartGADTMap (
918
- myConstraint,
919
- mapping,
920
- reverseMapping
921
- )
922
-
923
- def restore (other : GADTMap ): Unit = other match {
924
- case other : SmartGADTMap =>
925
- this .myConstraint = other.myConstraint
926
- this .mapping = other.mapping
927
- this .reverseMapping = other.reverseMapping
928
- case _ => ;
929
- }
930
-
931
- override def isEmpty : Boolean = mapping.size == 0
932
-
933
- // ---- Private ----------------------------------------------------------
934
-
935
- private [this ] def tvar (sym : Symbol )(implicit ctx : Context ): TypeVar = {
936
- mapping(sym) match {
937
- case tv : TypeVar =>
938
- tv
939
- case null =>
940
- val res = {
941
- import NameKinds .DepParamName
942
- // avoid registering the TypeVar with TyperState / TyperState#constraint
943
- // - we don't want TyperState instantiating these TypeVars
944
- // - we don't want TypeComparer constraining these TypeVars
945
- val poly = PolyType (DepParamName .fresh(sym.name.toTypeName) :: Nil )(
946
- pt => (sym.info match {
947
- case tb @ TypeBounds (_, hi) if hi.isLambdaSub => tb
948
- case _ => TypeBounds .empty
949
- }) :: Nil ,
950
- pt => defn.AnyType )
951
- new TypeVar (poly.paramRefs.head, creatorState = null )
952
- }
953
- gadts.println(i " GADTMap: created tvar $sym -> $res" )
954
- constraint = constraint.add(res.origin.binder, res :: Nil )
955
- mapping = mapping.updated(sym, res)
956
- reverseMapping = reverseMapping.updated(res.origin, sym)
957
- res
958
- }
959
- }
960
-
961
- // ---- Debug ------------------------------------------------------------
962
-
963
- override def constr_println (msg : => String ): Unit = gadtsConstr.println(msg)
964
-
965
- override def toText (printer : Printer ): Texts .Text = constraint.toText(printer)
966
-
967
- override def debugBoundsDescription (implicit ctx : Context ): String = {
968
- val sb = new mutable.StringBuilder
969
- sb ++= constraint.show
970
- sb += '\n '
971
- mapping.foreachBinding { case (sym, _) =>
972
- sb ++= i " $sym: ${fullBounds(sym)}\n "
973
- }
974
- sb.result
975
- }
976
- }
977
-
978
- @ sharable object EmptyGADTMap extends GADTMap {
979
- override def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit = unsupported(" EmptyGADTMap.addEmptyBounds" )
980
- override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = unsupported(" EmptyGADTMap.addBound" )
981
- override def isLess (sym1 : Symbol , sym2 : Symbol )(implicit ctx : Context ): Boolean = unsupported(" EmptyGADTMap.isLess" )
982
- override def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = null
983
- override def fullBounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = null
984
- override def contains (sym : Symbol )(implicit ctx : Context ) = false
985
- override def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type = unsupported(" EmptyGADTMap.approximation" )
986
- override def toText (printer : Printer ): Texts .Text = " EmptyGADTMap"
987
- override def debugBoundsDescription (implicit ctx : Context ): String = " EmptyGADTMap"
988
- override def fresh = new SmartGADTMap
989
- override def restore (other : GADTMap ): Unit = {
990
- if (! other.isEmpty) sys.error(" cannot restore a non-empty GADTMap" )
991
- }
992
- override def isEmpty : Boolean = true
993
- }
994
777
}
0 commit comments