@@ -3,7 +3,7 @@ package dotc
3
3
package core
4
4
5
5
import Types ._ , Contexts ._ , Symbols ._ , Decorators ._ , TypeApplications ._
6
- import util .SimpleIdentityMap
6
+ import util .{ SimpleIdentitySet , SimpleIdentityMap }
7
7
import collection .mutable
8
8
import printing .Printer
9
9
import printing .Texts ._
@@ -24,12 +24,14 @@ object OrderingConstraint {
24
24
/** The type of `OrderingConstraint#lowerMap`, `OrderingConstraint#upperMap` */
25
25
type ParamOrdering = ArrayValuedMap [List [TypeParamRef ]]
26
26
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 =
29
31
if boundsMap.isEmpty && lowerMap.isEmpty && upperMap.isEmpty then
30
32
empty
31
33
else
32
- val result = new OrderingConstraint (boundsMap, lowerMap, upperMap)
34
+ val result = new OrderingConstraint (boundsMap, lowerMap, upperMap, hardVars )
33
35
if ctx.run != null then ctx.run.nn.recordConstraintSize(result, result.boundsMap.size)
34
36
result
35
37
@@ -91,28 +93,28 @@ object OrderingConstraint {
91
93
def entries (c : OrderingConstraint , poly : TypeLambda ): Array [Type ] | Null =
92
94
c.boundsMap(poly)
93
95
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 )
95
97
def initial = NoType
96
98
}
97
99
98
100
val lowerLens : ConstraintLens [List [TypeParamRef ]] = new ConstraintLens [List [TypeParamRef ]] {
99
101
def entries (c : OrderingConstraint , poly : TypeLambda ): Array [List [TypeParamRef ]] | Null =
100
102
c.lowerMap(poly)
101
103
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 )
103
105
def initial = Nil
104
106
}
105
107
106
108
val upperLens : ConstraintLens [List [TypeParamRef ]] = new ConstraintLens [List [TypeParamRef ]] {
107
109
def entries (c : OrderingConstraint , poly : TypeLambda ): Array [List [TypeParamRef ]] | Null =
108
110
c.upperMap(poly)
109
111
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 )
111
113
def initial = Nil
112
114
}
113
115
114
116
@ 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 )
116
118
}
117
119
118
120
import OrderingConstraint ._
@@ -134,10 +136,13 @@ import OrderingConstraint._
134
136
* @param upperMap a map from TypeLambdas to arrays. Each array entry corresponds
135
137
* to a parameter P of the type lambda; it contains all constrained parameters
136
138
* 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.
137
141
*/
138
142
class OrderingConstraint (private val boundsMap : ParamBounds ,
139
143
private val lowerMap : ParamOrdering ,
140
- private val upperMap : ParamOrdering ) extends Constraint {
144
+ private val upperMap : ParamOrdering ,
145
+ private val hardVars : TypeVars ) extends Constraint {
141
146
142
147
import UnificationDirection .*
143
148
@@ -277,7 +282,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
277
282
val entries1 = new Array [Type ](nparams * 2 )
278
283
poly.paramInfos.copyToArray(entries1, 0 )
279
284
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)
281
286
}
282
287
283
288
/** Split dependent parameters off the bounds for parameters in `poly`.
@@ -478,7 +483,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
478
483
}
479
484
po.remove(pt).mapValuesNow(removeFromBoundss)
480
485
}
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)
482
488
.checkNonCyclic()
483
489
}
484
490
@@ -505,7 +511,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
505
511
def swapKey [T ](m : ArrayValuedMap [T ]) =
506
512
val info = m(from)
507
513
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 )
509
515
def subst [T <: Type ](x : T ): T = x.subst(from, to).asInstanceOf [T ]
510
516
current.foreachParam {(p, i) =>
511
517
current = boundsLens.map(this , current, p, i, subst)
@@ -515,6 +521,11 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
515
521
constr.println(i " renamed $this to $current" )
516
522
current.checkNonCyclic()
517
523
524
+ def isHard (tv : TypeVar ) = hardVars.contains(tv)
525
+
526
+ def withHard (tv : TypeVar )(using Context ) =
527
+ newConstraint(boundsMap, lowerMap, upperMap, hardVars + tv)
528
+
518
529
def instType (tvar : TypeVar ): Type = entry(tvar.origin) match
519
530
case _ : TypeBounds => NoType
520
531
case tp : TypeParamRef => typeVarOfParam(tp).orElse(tp)
0 commit comments