@@ -18,15 +18,18 @@ import config.Printers.{constr, typr}
1818 * By comparison: Constraint handlers are parts of type comparers and can use their functionality. 
1919 * Constraint handlers update the current constraint as a side effect. 
2020 */  
21- trait  ConstraintHandling  {
21+ trait  ConstraintHandling [ AbstractContext ]  {
2222
23-   implicit  val  ctx :  Context 
23+   def  constr_println (msg : =>  String ):  Unit  =  constr.println(msg)
24+   def  typr_println (msg : =>  String ):  Unit  =  typr.println(msg)
2425
25-   protected  def  isSubType (tp1 : Type , tp2 : Type ):  Boolean 
26-   protected  def  isSameType (tp1 : Type , tp2 : Type ):  Boolean 
26+   implicit  def  ctx (implicit  ac : AbstractContext ):  Context 
2727
28-   val  state :  TyperState 
29-   import  state .constraint 
28+   protected  def  isSubType (tp1 : Type , tp2 : Type )(implicit  actx : AbstractContext ):  Boolean 
29+   protected  def  isSameType (tp1 : Type , tp2 : Type )(implicit  actx : AbstractContext ):  Boolean 
30+ 
31+   protected  def  constraint :  Constraint 
32+   protected  def  constraint_= (c : Constraint ):  Unit 
3033
3134  private [this ] var  addConstraintInvocations  =  0 
3235
@@ -50,7 +53,20 @@ trait ConstraintHandling {
5053   */  
5154  protected  var  comparedTypeLambdas :  Set [TypeLambda ] =  Set .empty
5255
53-   protected  def  addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean ):  Boolean  = 
56+   /**  Gives for each instantiated type var that does not yet have its `inst` field 
57+     *  set, the instance value stored in the constraint. Storing instances in constraints 
58+     *  is done only in a temporary way for contexts that may be retracted 
59+     *  without also retracting the type var as a whole. 
60+     */  
61+   def  instType (tvar : TypeVar ):  Type  =  constraint.entry(tvar.origin) match  {
62+     case  _ : TypeBounds  =>  NoType 
63+     case  tp : TypeParamRef  => 
64+       var  tvar1  =  constraint.typeVarOfParam(tp)
65+       if  (tvar1.exists) tvar1 else  tp
66+     case  tp =>  tp
67+   }
68+ 
69+   protected  def  addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean )(implicit  actx : AbstractContext ):  Boolean  = 
5470    ! constraint.contains(param) ||  {
5571      def  occursIn (bound : Type ):  Boolean  =  {
5672        val  b  =  bound.dealias
@@ -100,34 +116,34 @@ trait ConstraintHandling {
100116
101117  private  def  location (implicit  ctx : Context ) =  " "   //  i"in ${ctx.typerState.stateChainStr}" // use for debugging
102118
103-   protected  def  addUpperBound (param : TypeParamRef , bound : Type ):  Boolean  =  {
119+   protected  def  addUpperBound (param : TypeParamRef , bound : Type )( implicit   actx :  AbstractContext ) :  Boolean  =  {
104120    def  description  =  i " constraint  $param <:  $bound to \n $constraint" 
105121    if  (bound.isRef(defn.NothingClass ) &&  ctx.typerState.isGlobalCommittable) {
106122      def  msg  =  s " !!! instantiated to Nothing:  $param, constraint =  ${constraint.show}" 
107123      if  (Config .failOnInstantiationToNothing) assert(false , msg)
108124      else  ctx.log(msg)
109125    }
110-     constr.println (i " adding  $description$location" )
126+     constr_println (i " adding  $description$location" )
111127    val  lower  =  constraint.lower(param)
112128    val  res  = 
113129      addOneBound(param, bound, isUpper =  true ) && 
114130      lower.forall(addOneBound(_, bound, isUpper =  true ))
115-     constr.println (i " added  $description =  $res$location" )
131+     constr_println (i " added  $description =  $res$location" )
116132    res
117133  }
118134
119-   protected  def  addLowerBound (param : TypeParamRef , bound : Type ):  Boolean  =  {
135+   protected  def  addLowerBound (param : TypeParamRef , bound : Type )( implicit   actx :  AbstractContext ) :  Boolean  =  {
120136    def  description  =  i " constraint  $param >:  $bound to \n $constraint" 
121-     constr.println (i " adding  $description" )
137+     constr_println (i " adding  $description" )
122138    val  upper  =  constraint.upper(param)
123139    val  res  = 
124140      addOneBound(param, bound, isUpper =  false ) && 
125141      upper.forall(addOneBound(_, bound, isUpper =  false ))
126-     constr.println (i " added  $description =  $res$location" )
142+     constr_println (i " added  $description =  $res$location" )
127143    res
128144  }
129145
130-   protected  def  addLess (p1 : TypeParamRef , p2 : TypeParamRef ):  Boolean  =  {
146+   protected  def  addLess (p1 : TypeParamRef , p2 : TypeParamRef )( implicit   actx :  AbstractContext ) :  Boolean  =  {
131147    def  description  =  i " ordering  $p1 <:  $p2 to \n $constraint" 
132148    val  res  = 
133149      if  (constraint.isLess(p2, p1)) unify(p2, p1)
@@ -136,20 +152,20 @@ trait ConstraintHandling {
136152        val  up2  =  p2 ::  constraint.exclusiveUpper(p2, p1)
137153        val  lo1  =  constraint.nonParamBounds(p1).lo
138154        val  hi2  =  constraint.nonParamBounds(p2).hi
139-         constr.println (i " adding  $description down1 =  $down1, up2 =  $up2$location" )
155+         constr_println (i " adding  $description down1 =  $down1, up2 =  $up2$location" )
140156        constraint =  constraint.addLess(p1, p2)
141157        down1.forall(addOneBound(_, hi2, isUpper =  true )) && 
142158        up2.forall(addOneBound(_, lo1, isUpper =  false ))
143159      }
144-     constr.println (i " added  $description =  $res$location" )
160+     constr_println (i " added  $description =  $res$location" )
145161    res
146162  }
147163
148164  /**  Make p2 = p1, transfer all bounds of p2 to p1 
149165   *  @pre  less(p1)(p2) 
150166   */  
151-   private  def  unify (p1 : TypeParamRef , p2 : TypeParamRef ):  Boolean  =  {
152-     constr.println (s " unifying  $p1  $p2" )
167+   private  def  unify (p1 : TypeParamRef , p2 : TypeParamRef )( implicit   actx :  AbstractContext ) :  Boolean  =  {
168+     constr_println (s " unifying  $p1  $p2" )
153169    assert(constraint.isLess(p1, p2))
154170    val  down  =  constraint.exclusiveLower(p2, p1)
155171    val  up  =  constraint.exclusiveUpper(p1, p2)
@@ -163,7 +179,7 @@ trait ConstraintHandling {
163179  }
164180
165181
166-   protected  def  isSubType (tp1 : Type , tp2 : Type , whenFrozen : Boolean ):  Boolean  =  {
182+   protected  def  isSubType (tp1 : Type , tp2 : Type , whenFrozen : Boolean )( implicit   actx :  AbstractContext ) :  Boolean  =  {
167183    if  (whenFrozen)
168184      isSubTypeWhenFrozen(tp1, tp2)
169185    else 
@@ -182,13 +198,13 @@ trait ConstraintHandling {
182198    }
183199  }
184200
185-   final  def  isSubTypeWhenFrozen (tp1 : Type , tp2 : Type ):  Boolean  =  inFrozenConstraint(isSubType(tp1, tp2))
186-   final  def  isSameTypeWhenFrozen (tp1 : Type , tp2 : Type ):  Boolean  =  inFrozenConstraint(isSameType(tp1, tp2))
201+   final  def  isSubTypeWhenFrozen (tp1 : Type , tp2 : Type )( implicit   actx :  AbstractContext ) :  Boolean  =  inFrozenConstraint(isSubType(tp1, tp2))
202+   final  def  isSameTypeWhenFrozen (tp1 : Type , tp2 : Type )( implicit   actx :  AbstractContext ) :  Boolean  =  inFrozenConstraint(isSameType(tp1, tp2))
187203
188204  /**  Test whether the lower bounds of all parameters in this 
189205   *  constraint are a solution to the constraint. 
190206   */  
191-   protected  final  def  isSatisfiable :  Boolean  = 
207+   protected  final  def  isSatisfiable ( implicit   actx :  AbstractContext ) :  Boolean  = 
192208    constraint.forallParams { param => 
193209      val  TypeBounds (lo, hi) =  constraint.entry(param)
194210      isSubType(lo, hi) ||  {
@@ -207,7 +223,7 @@ trait ConstraintHandling {
207223   *  @return  the instantiating type 
208224   *  @pre `param` is in the constraint's domain. 
209225   */  
210-   final  def  approximation (param : TypeParamRef , fromBelow : Boolean ):  Type  =  {
226+   final  def  approximation (param : TypeParamRef , fromBelow : Boolean )( implicit   actx :  AbstractContext ) :  Type  =  {
211227    val  avoidParam  =  new  TypeMap  {
212228      override  def  stopAtStatic  =  true 
213229      def  avoidInArg (arg : Type ):  Type  = 
@@ -247,7 +263,7 @@ trait ConstraintHandling {
247263      case  _ : TypeBounds  => 
248264        val  bound  =  if  (fromBelow) constraint.fullLowerBound(param) else  constraint.fullUpperBound(param)
249265        val  inst  =  avoidParam(bound)
250-         typr.println (s " approx  ${param.show}, from below =  $fromBelow, bound =  ${bound.show}, inst =  ${inst.show}" )
266+         typr_println (s " approx  ${param.show}, from below =  $fromBelow, bound =  ${bound.show}, inst =  ${inst.show}" )
251267        inst
252268      case  inst => 
253269        assert(inst.exists, i " param =  $param\n constraint =  $constraint" )
@@ -261,7 +277,7 @@ trait ConstraintHandling {
261277   *   2. If `tp` is a union type, yet upper bound is not a union type, 
262278   *      approximate the union type from above by an intersection of all common base types. 
263279   */  
264-   def  widenInferred (tp : Type , bound : Type ):  Type  =  {
280+   def  widenInferred (tp : Type , bound : Type )( implicit   actx :  AbstractContext ) :  Type  =  {
265281    def  isMultiSingleton (tp : Type ):  Boolean  =  tp.stripAnnots match  {
266282      case  tp : SingletonType  =>  true 
267283      case  AndType (tp1, tp2) =>  isMultiSingleton(tp1) |  isMultiSingleton(tp2)
@@ -294,7 +310,7 @@ trait ConstraintHandling {
294310   *  a lower bound instantiation can be a singleton type only if the upper bound 
295311   *  is also a singleton type. 
296312   */  
297-   def  instanceType (param : TypeParamRef , fromBelow : Boolean ):  Type  =  {
313+   def  instanceType (param : TypeParamRef , fromBelow : Boolean )( implicit   actx :  AbstractContext ) :  Type  =  {
298314    val  inst  =  approximation(param, fromBelow).simplified
299315    if  (fromBelow) widenInferred(inst, constraint.fullUpperBound(param)) else  inst
300316  }
@@ -309,7 +325,7 @@ trait ConstraintHandling {
309325   *  Both `c1` and `c2` are required to derive from constraint `pre`, possibly 
310326   *  narrowing it with further bounds. 
311327   */  
312-   protected  final  def  subsumes (c1 : Constraint , c2 : Constraint , pre : Constraint ):  Boolean  = 
328+   protected  final  def  subsumes (c1 : Constraint , c2 : Constraint , pre : Constraint )( implicit   actx :  AbstractContext ) :  Boolean  = 
313329    if  (c2 eq pre) true 
314330    else  if  (c1 eq pre) false 
315331    else  {
@@ -323,7 +339,7 @@ trait ConstraintHandling {
323339    }
324340
325341  /**  The current bounds of type parameter `param` */  
326-   def  bounds (param : TypeParamRef ):  TypeBounds  =  {
342+   def  bounds (param : TypeParamRef )( implicit   actx :  AbstractContext ) :  TypeBounds  =  {
327343    val  e  =  constraint.entry(param)
328344    if  (e.exists) e.bounds
329345    else  {
@@ -337,7 +353,7 @@ trait ConstraintHandling {
337353   *  and propagate all bounds. 
338354   *  @param  tvars    See Constraint#add 
339355   */  
340-   def  addToConstraint (tl : TypeLambda , tvars : List [TypeVar ]):  Boolean  = 
356+   def  addToConstraint (tl : TypeLambda , tvars : List [TypeVar ])( implicit   actx :  AbstractContext ) :  Boolean  = 
341357    checkPropagated(i " initialized  $tl" ) {
342358      constraint =  constraint.add(tl, tvars)
343359      tl.paramRefs.forall { param => 
@@ -346,7 +362,7 @@ trait ConstraintHandling {
346362            val  lower  =  constraint.lower(param)
347363            val  upper  =  constraint.upper(param)
348364            if  (lower.nonEmpty &&  ! bounds.lo.isRef(defn.NothingClass ) || 
349-               upper.nonEmpty &&  ! bounds.hi.isRef(defn.AnyClass )) constr.println (i " INIT***  $tl" )
365+               upper.nonEmpty &&  ! bounds.hi.isRef(defn.AnyClass )) constr_println (i " INIT***  $tl" )
350366            lower.forall(addOneBound(_, bounds.hi, isUpper =  true )) && 
351367              upper.forall(addOneBound(_, bounds.lo, isUpper =  false ))
352368          case  _ => 
@@ -365,7 +381,7 @@ trait ConstraintHandling {
365381   *  This holds if `TypeVarsMissContext` is set unless `param` is a part 
366382   *  of a MatchType that is currently normalized. 
367383   */  
368-   final  def  assumedTrue (param : TypeParamRef ):  Boolean  = 
384+   final  def  assumedTrue (param : TypeParamRef )( implicit   actx :  AbstractContext ) :  Boolean  = 
369385    ctx.mode.is(Mode .TypevarsMissContext ) &&  (caseLambda `ne` param.binder)
370386
371387  /**  Add constraint `param <: bound` if `fromBelow` is false, `param >: bound` otherwise. 
@@ -375,7 +391,7 @@ trait ConstraintHandling {
375391   *  not be AndTypes and lower bounds may not be OrTypes. This is assured by the 
376392   *  way isSubType is organized. 
377393   */  
378-   protected  def  addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean ):  Boolean  =  {
394+   protected  def  addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean )( implicit   actx :  AbstractContext ) :  Boolean  =  {
379395    def  description  =  i " constr  $param  ${if  (fromBelow) " >:"   else  " <:"  }  $bound: \n $constraint" 
380396    // checkPropagated(s"adding $description")(true) // DEBUG in case following fails
381397    checkPropagated(s " added  $description" ) {
@@ -491,7 +507,7 @@ trait ConstraintHandling {
491507  }
492508
493509  /**  Instantiate `param` to `tp` if the constraint stays satisfiable */  
494-   protected  def  tryInstantiate (param : TypeParamRef , tp : Type ):  Boolean  =  {
510+   protected  def  tryInstantiate (param : TypeParamRef , tp : Type )( implicit   actx :  AbstractContext ) :  Boolean  =  {
495511    val  saved  =  constraint
496512    constraint = 
497513      if  (addConstraint(param, tp, fromBelow =  true ) && 
@@ -501,7 +517,7 @@ trait ConstraintHandling {
501517  }
502518
503519  /**  Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */  
504-   def  checkPropagated (msg : =>  String )(result : Boolean ):  Boolean  =  {
520+   def  checkPropagated (msg : =>  String )(result : Boolean )( implicit   actx :  AbstractContext ) :  Boolean  =  {
505521    if  (Config .checkConstraintsPropagated &&  result &&  addConstraintInvocations ==  0 ) {
506522      inFrozenConstraint {
507523        for  (p <-  constraint.domainParams) {
0 commit comments