@@ -139,9 +139,9 @@ object Contexts {
139139 final def importInfo : ImportInfo = _importInfo
140140
141141 /** 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
145145
146146 /** The history of implicit searches that are currently active */
147147 private [this ] var _searchHistory : SearchHistory = null
@@ -534,7 +534,7 @@ object Contexts {
534534 def setTypeAssigner (typeAssigner : TypeAssigner ): this .type = { this .typeAssigner = typeAssigner; this }
535535 def setTyper (typer : Typer ): this .type = { this .scope = typer.scope; setTypeAssigner(typer) }
536536 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 }
538538 def setFreshGADTBounds : this .type = setGadt(gadt.fresh)
539539 def setSearchHistory (searchHistory : SearchHistory ): this .type = { this .searchHistory = searchHistory; this }
540540 def setSource (source : SourceFile ): this .type = { this .source = source; this }
@@ -617,7 +617,7 @@ object Contexts {
617617 store = initialStore.updated(settingsStateLoc, settingsGroup.defaultState)
618618 typeComparer = new TypeComparer (this )
619619 searchHistory = new SearchRoot
620- gadt = EmptyGADTMap
620+ gadt = EmptyGadtConstraint
621621 }
622622
623623 @ sharable object NoContext extends Context (null ) {
@@ -774,233 +774,4 @@ object Contexts {
774774 if (thread == null ) thread = Thread .currentThread()
775775 else assert(thread == Thread .currentThread(), " illegal multithreaded access to ContextBase" )
776776 }
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- }
1006777}
0 commit comments