@@ -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,217 +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 def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit = tvar(sym)
834
-
835
- override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = {
836
- @ annotation.tailrec def stripInternalTypeVar (tp : Type ): Type = tp match {
837
- case tv : TypeVar =>
838
- val inst = instType(tv)
839
- if (inst.exists) stripInternalTypeVar(inst) else tv
840
- case _ => tp
841
- }
842
-
843
- val symTvar : TypeVar = stripInternalTypeVar(tvar(sym)) match {
844
- case tv : TypeVar => tv
845
- case inst =>
846
- gadts.println(i " instantiated: $sym -> $inst" )
847
- return if (isUpper) isSubType(inst , bound) else isSubType(bound, inst)
848
- }
849
-
850
- val internalizedBound = bound match {
851
- case nt : NamedType if contains(nt.symbol) =>
852
- stripInternalTypeVar(tvar(nt.symbol))
853
- case _ => bound
854
- }
855
- (
856
- internalizedBound match {
857
- case boundTvar : TypeVar =>
858
- if (boundTvar eq symTvar) true
859
- else if (isUpper) addLess(symTvar.origin, boundTvar.origin)
860
- else addLess(boundTvar.origin, symTvar.origin)
861
- case bound =>
862
- val oldUpperBound = bounds(symTvar.origin)
863
- // If we already have bounds `F >: [t] => List[t] <: [t] => Any`
864
- // and we want to record that `F <: [+A] => List[A]`, we need to adapt
865
- // type parameter variances of the bound. Consider that the following is valid:
866
- //
867
- // class Foo[F[t] >: List[t]]
868
- // type T = Foo[List]
869
- //
870
- // precisely because `Foo[List]` is desugared to `Foo[[A] => List[A]]`.
871
- val bound1 = bound.adaptHkVariances(oldUpperBound)
872
- if (isUpper) addUpperBound(symTvar.origin, bound1)
873
- else addLowerBound(symTvar.origin, bound1)
874
- }
875
- ).reporting({ res =>
876
- val descr = if (isUpper) " upper" else " lower"
877
- val op = if (isUpper) " <:" else " >:"
878
- i " adding $descr bound $sym $op $bound = $res\t ( $symTvar $op $internalizedBound ) "
879
- }, gadts)
880
- }
881
-
882
- override def isLess (sym1 : Symbol , sym2 : Symbol )(implicit ctx : Context ): Boolean =
883
- constraint.isLess(tvar(sym1).origin, tvar(sym2).origin)
884
-
885
- override def fullBounds (sym : Symbol )(implicit ctx : Context ): TypeBounds =
886
- mapping(sym) match {
887
- case null => null
888
- case tv => fullBounds(tv.origin)
889
- }
890
-
891
- override def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = {
892
- mapping(sym) match {
893
- case null => null
894
- case tv =>
895
- def retrieveBounds : TypeBounds =
896
- bounds(tv.origin) match {
897
- case TypeAlias (tpr : TypeParamRef ) if reverseMapping.contains(tpr) =>
898
- TypeAlias (reverseMapping(tpr).typeRef)
899
- case tb => tb
900
- }
901
- retrieveBounds// .reporting({ res => i"gadt bounds $sym: $res" }, gadts)
902
- }
903
- }
904
-
905
- override def contains (sym : Symbol )(implicit ctx : Context ): Boolean = mapping(sym) ne null
906
-
907
- override def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type = {
908
- val res = approximation(tvar(sym).origin, fromBelow = fromBelow)
909
- gadts.println(i " approximating $sym ~> $res" )
910
- res
911
- }
912
-
913
- override def fresh : GADTMap = new SmartGADTMap (
914
- myConstraint,
915
- mapping,
916
- reverseMapping
917
- )
918
-
919
- def restore (other : GADTMap ): Unit = other match {
920
- case other : SmartGADTMap =>
921
- this .myConstraint = other.myConstraint
922
- this .mapping = other.mapping
923
- this .reverseMapping = other.reverseMapping
924
- case _ => ;
925
- }
926
-
927
- override def isEmpty : Boolean = mapping.size == 0
928
-
929
- // ---- Private ----------------------------------------------------------
930
-
931
- private [this ] def tvar (sym : Symbol )(implicit ctx : Context ): TypeVar = {
932
- mapping(sym) match {
933
- case tv : TypeVar =>
934
- tv
935
- case null =>
936
- val res = {
937
- import NameKinds .DepParamName
938
- // avoid registering the TypeVar with TyperState / TyperState#constraint
939
- // - we don't want TyperState instantiating these TypeVars
940
- // - we don't want TypeComparer constraining these TypeVars
941
- val poly = PolyType (DepParamName .fresh(sym.name.toTypeName) :: Nil )(
942
- pt => (sym.info match {
943
- case tb @ TypeBounds (_, hi) if hi.isLambdaSub => tb
944
- case _ => TypeBounds .empty
945
- }) :: Nil ,
946
- pt => defn.AnyType )
947
- new TypeVar (poly.paramRefs.head, creatorState = null )
948
- }
949
- gadts.println(i " GADTMap: created tvar $sym -> $res" )
950
- constraint = constraint.add(res.origin.binder, res :: Nil )
951
- mapping = mapping.updated(sym, res)
952
- reverseMapping = reverseMapping.updated(res.origin, sym)
953
- res
954
- }
955
- }
956
-
957
- // ---- Debug ------------------------------------------------------------
958
-
959
- override def constr_println (msg : => String ): Unit = gadtsConstr.println(msg)
960
-
961
- override def toText (printer : Printer ): Texts .Text = constraint.toText(printer)
962
-
963
- override def debugBoundsDescription (implicit ctx : Context ): String = {
964
- val sb = new mutable.StringBuilder
965
- sb ++= constraint.show
966
- sb += '\n '
967
- mapping.foreachBinding { case (sym, _) =>
968
- sb ++= i " $sym: ${fullBounds(sym)}\n "
969
- }
970
- sb.result
971
- }
972
- }
973
-
974
- @ sharable object EmptyGADTMap extends GADTMap {
975
- override def addEmptyBounds (sym : Symbol )(implicit ctx : Context ): Unit = unsupported(" EmptyGADTMap.addEmptyBounds" )
976
- override def addBound (sym : Symbol , bound : Type , isUpper : Boolean )(implicit ctx : Context ): Boolean = unsupported(" EmptyGADTMap.addBound" )
977
- override def isLess (sym1 : Symbol , sym2 : Symbol )(implicit ctx : Context ): Boolean = unsupported(" EmptyGADTMap.isLess" )
978
- override def bounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = null
979
- override def fullBounds (sym : Symbol )(implicit ctx : Context ): TypeBounds = null
980
- override def contains (sym : Symbol )(implicit ctx : Context ) = false
981
- override def approximation (sym : Symbol , fromBelow : Boolean )(implicit ctx : Context ): Type = unsupported(" EmptyGADTMap.approximation" )
982
- override def toText (printer : Printer ): Texts .Text = " EmptyGADTMap"
983
- override def debugBoundsDescription (implicit ctx : Context ): String = " EmptyGADTMap"
984
- override def fresh = new SmartGADTMap
985
- override def restore (other : GADTMap ): Unit = {
986
- if (! other.isEmpty) sys.error(" cannot restore a non-empty GADTMap" )
987
- }
988
- override def isEmpty : Boolean = true
989
- }
990
777
}
0 commit comments