@@ -3,7 +3,7 @@ package dotc
33package core
44
55import Types ._ , Contexts ._ , Symbols ._ , Decorators ._ , TypeApplications ._
6- import util .SimpleIdentityMap
6+ import util .{ SimpleIdentitySet , SimpleIdentityMap }
77import collection .mutable
88import printing .Printer
99import printing .Texts ._
@@ -24,12 +24,14 @@ object OrderingConstraint {
2424 /** The type of `OrderingConstraint#lowerMap`, `OrderingConstraint#upperMap` */
2525 type ParamOrdering = ArrayValuedMap [List [TypeParamRef ]]
2626
27- /** A new constraint with given maps */
28- private def newConstraint (boundsMap : ParamBounds , lowerMap : ParamOrdering , upperMap : ParamOrdering )(using Context ) : OrderingConstraint =
27+ /** A new constraint with given maps and given set of hard typevars */
28+ private def newConstraint (
29+ boundsMap : ParamBounds , lowerMap : ParamOrdering , upperMap : ParamOrdering ,
30+ hardVars : TypeVars )(using Context ) : OrderingConstraint =
2931 if boundsMap.isEmpty && lowerMap.isEmpty && upperMap.isEmpty then
3032 empty
3133 else
32- val result = new OrderingConstraint (boundsMap, lowerMap, upperMap)
34+ val result = new OrderingConstraint (boundsMap, lowerMap, upperMap, hardVars )
3335 if ctx.run != null then ctx.run.nn.recordConstraintSize(result, result.boundsMap.size)
3436 result
3537
@@ -91,28 +93,28 @@ object OrderingConstraint {
9193 def entries (c : OrderingConstraint , poly : TypeLambda ): Array [Type ] | Null =
9294 c.boundsMap(poly)
9395 def updateEntries (c : OrderingConstraint , poly : TypeLambda , entries : Array [Type ])(using Context ): OrderingConstraint =
94- newConstraint(c.boundsMap.updated(poly, entries), c.lowerMap, c.upperMap)
96+ newConstraint(c.boundsMap.updated(poly, entries), c.lowerMap, c.upperMap, c.hardVars )
9597 def initial = NoType
9698 }
9799
98100 val lowerLens : ConstraintLens [List [TypeParamRef ]] = new ConstraintLens [List [TypeParamRef ]] {
99101 def entries (c : OrderingConstraint , poly : TypeLambda ): Array [List [TypeParamRef ]] | Null =
100102 c.lowerMap(poly)
101103 def updateEntries (c : OrderingConstraint , poly : TypeLambda , entries : Array [List [TypeParamRef ]])(using Context ): OrderingConstraint =
102- newConstraint(c.boundsMap, c.lowerMap.updated(poly, entries), c.upperMap)
104+ newConstraint(c.boundsMap, c.lowerMap.updated(poly, entries), c.upperMap, c.hardVars )
103105 def initial = Nil
104106 }
105107
106108 val upperLens : ConstraintLens [List [TypeParamRef ]] = new ConstraintLens [List [TypeParamRef ]] {
107109 def entries (c : OrderingConstraint , poly : TypeLambda ): Array [List [TypeParamRef ]] | Null =
108110 c.upperMap(poly)
109111 def updateEntries (c : OrderingConstraint , poly : TypeLambda , entries : Array [List [TypeParamRef ]])(using Context ): OrderingConstraint =
110- newConstraint(c.boundsMap, c.lowerMap, c.upperMap.updated(poly, entries))
112+ newConstraint(c.boundsMap, c.lowerMap, c.upperMap.updated(poly, entries), c.hardVars )
111113 def initial = Nil
112114 }
113115
114116 @ sharable
115- val empty = new OrderingConstraint (SimpleIdentityMap .empty, SimpleIdentityMap .empty, SimpleIdentityMap .empty)
117+ val empty = new OrderingConstraint (SimpleIdentityMap .empty, SimpleIdentityMap .empty, SimpleIdentityMap .empty, SimpleIdentitySet .empty )
116118}
117119
118120import OrderingConstraint ._
@@ -134,10 +136,13 @@ import OrderingConstraint._
134136 * @param upperMap a map from TypeLambdas to arrays. Each array entry corresponds
135137 * to a parameter P of the type lambda; it contains all constrained parameters
136138 * Q that are known to be greater than P, i.e. P <: Q.
139+ * @param hardVars a set of type variables that are marked as hard and therefore will not
140+ * undergo a `widenUnion` when instantiated to their lower bound.
137141 */
138142class OrderingConstraint (private val boundsMap : ParamBounds ,
139143 private val lowerMap : ParamOrdering ,
140- private val upperMap : ParamOrdering ) extends Constraint {
144+ private val upperMap : ParamOrdering ,
145+ private val hardVars : TypeVars ) extends Constraint {
141146
142147 import UnificationDirection .*
143148
@@ -277,7 +282,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
277282 val entries1 = new Array [Type ](nparams * 2 )
278283 poly.paramInfos.copyToArray(entries1, 0 )
279284 tvars.copyToArray(entries1, nparams)
280- newConstraint(boundsMap.updated(poly, entries1), lowerMap, upperMap).init(poly)
285+ newConstraint(boundsMap.updated(poly, entries1), lowerMap, upperMap, hardVars ).init(poly)
281286 }
282287
283288 /** Split dependent parameters off the bounds for parameters in `poly`.
@@ -478,7 +483,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
478483 }
479484 po.remove(pt).mapValuesNow(removeFromBoundss)
480485 }
481- newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap))
486+ val hardVars1 = pt.paramRefs.foldLeft(hardVars)((hvs, param) => hvs - typeVarOfParam(param))
487+ newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap), hardVars1)
482488 .checkNonCyclic()
483489 }
484490
@@ -505,7 +511,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
505511 def swapKey [T ](m : ArrayValuedMap [T ]) =
506512 val info = m(from)
507513 if info == null then m else m.remove(from).updated(to, info)
508- var current = newConstraint(swapKey(boundsMap), swapKey(lowerMap), swapKey(upperMap))
514+ var current = newConstraint(swapKey(boundsMap), swapKey(lowerMap), swapKey(upperMap), hardVars )
509515 def subst [T <: Type ](x : T ): T = x.subst(from, to).asInstanceOf [T ]
510516 current.foreachParam {(p, i) =>
511517 current = boundsLens.map(this , current, p, i, subst)
@@ -515,6 +521,11 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
515521 constr.println(i " renamed $this to $current" )
516522 current.checkNonCyclic()
517523
524+ def isHard (tv : TypeVar ) = hardVars.contains(tv)
525+
526+ def withHard (tv : TypeVar )(using Context ) =
527+ newConstraint(boundsMap, lowerMap, upperMap, hardVars + tv)
528+
518529 def instType (tvar : TypeVar ): Type = entry(tvar.origin) match
519530 case _ : TypeBounds => NoType
520531 case tp : TypeParamRef => typeVarOfParam(tp).orElse(tp)
0 commit comments