@@ -717,13 +717,23 @@ object Contexts {
717717    def  derived :  GADTMap 
718718  }
719719
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 
724726  ) extends  GADTMap  with  ConstraintHandling  {
725727    import  dotty .tools .dotc .config .Printers .gadts 
726728
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+ 
727737    override  def  debugBoundsDescription (implicit  ctx : Context ):  String  =  {
728738      val  sb  =  new  mutable.StringBuilder 
729739      sb ++=  constraint.show
@@ -734,6 +744,8 @@ object Contexts {
734744      sb.result
735745    }
736746
747+     private [this ] var  checkInProgress  =  false 
748+ 
737749    //  TODO: dirty kludge - should this class be an inner class of TyperState instead?
738750    private [this ] var  myCtx :  Context  =  null 
739751    implicit  override  def  ctx  =  myCtx
@@ -749,9 +761,10 @@ object Contexts {
749761    override  def  isSubType (tp1 : Type , tp2 : Type ):  Boolean  =  ctx.typeComparer.isSubType(tp1, tp2)
750762    override  def  isSameType (tp1 : Type , tp2 : Type ):  Boolean  =  ctx.typeComparer.isSameType(tp1, tp2)
751763
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
755768        case  null  => 
756769          val  res  =  {
757770            import  NameKinds .DepParamName 
@@ -769,12 +782,13 @@ object Contexts {
769782          reverseMapping =  reverseMapping.updated(res.origin, sym)
770783          res
771784      }
772-       res
773785    }
774786
775787    override  def  addEmptyBounds (sym : Symbol )(implicit  ctx : Context ):  Unit  =  tvar(sym)
776788
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 
778792      @ annotation.tailrec def  stripInst (tp : Type ):  Type  =  tp match  {
779793        case  tv : TypeVar  => 
780794          val  inst  =  instType(tv)
@@ -795,8 +809,8 @@ object Contexts {
795809
796810        val  outerCtx  =  ctx
797811        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)
800814
801815          //  TypeComparer.explain[Boolean](gadts.println) { implicit ctx =>
802816          if  (isSubtype) externalizedTp1 frozen_<:<  externalizedTp2
@@ -811,6 +825,7 @@ object Contexts {
811825        case  tv : TypeVar  =>  tv
812826        case  inst => 
813827          gadts.println(i " instantiated:  $sym ->  $inst" )
828+ //           return true
814829          return  cautiousSubtype(inst, bound, isSubtype =  isUpper, allowNarrowing =  true )
815830      }
816831
@@ -847,25 +862,47 @@ object Contexts {
847862        i " adding  $descr bound  $sym  $op  $bound =  $res\t (  $symTvar  $op  $tvarBound ) " 
848863      }
849864      res
850-     }
865+     }  finally  checkInProgress  =   false 
851866
852867    override  def  bounds (sym : Symbol )(implicit  ctx : Context ):  TypeBounds  =  inCtx(ctx) {
853868      mapping(sym) match  {
854869        case  null  =>  null 
855870        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" )
859894          res
860895      }
861896    }
862897
863898    override  def  contains (sym : Symbol )(implicit  ctx : Context ):  Boolean  =  mapping(sym) ne null 
864899
865900    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
869906    )
870907
871908    private  final  class  TypeVarInsertingMap  extends  TypeMap  {
0 commit comments