@@ -10,7 +10,7 @@ import printing.Texts._
10
10
import config .Config
11
11
import config .Printers .constr
12
12
import reflect .ClassTag
13
- import Constraint .TypeVarDeps
13
+ import Constraint .ReverseDeps
14
14
import NameKinds .DepParamName
15
15
import annotation .tailrec
16
16
import annotation .internal .sharable
@@ -225,122 +225,117 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
225
225
226
226
// ------------- TypeVar dependencies -----------------------------------
227
227
228
- var coDeps, contraDeps : TypeVarDeps = SimpleIdentityMap .empty
228
+ var coDeps, contraDeps : ReverseDeps = SimpleIdentityMap .empty
229
229
230
230
def dependsOn (tv : TypeVar , except : TypeVars , co : Boolean )(using Context ): Boolean =
231
- def test (deps : TypeVarDeps , lens : ConstraintLens [List [TypeParamRef ]]) =
232
- val tvdeps = deps(tv)
233
- null != tvdeps && tvdeps.exists(! except.contains(_))
234
- || lens(this , tv.origin.binder, tv.origin.paramNum).exists(
235
- p => ! except.contains(typeVarOfParam(p)))
231
+ def origin (tv : TypeVar ) =
232
+ assert(! tv.isInstantiated)
233
+ tv.origin
234
+ val param = origin(tv)
235
+ val excluded = except.map(origin)
236
+ def test (deps : ReverseDeps , lens : ConstraintLens [List [TypeParamRef ]]) =
237
+ val depending = deps(param)
238
+ null != depending && depending.exists(! excluded.contains(_))
239
+ || lens(this , tv.origin.binder, tv.origin.paramNum).exists(! excluded.contains(_))
236
240
// .showing(i"outer depends on $tv with ${tvdeps.toList}%, % = $result")
237
241
if co then test(coDeps, upperLens) else test(contraDeps, lowerLens)
238
242
239
- private class Adjuster (tvar : TypeVar )(using Context ) extends TypeTraverser :
243
+ private class Adjuster (srcParam : TypeParamRef )(using Context ) extends TypeTraverser :
240
244
var add : Boolean = compiletime.uninitialized
241
245
242
- def update (deps : TypeVarDeps , referenced : TypeVar ): TypeVarDeps =
246
+ def update (deps : ReverseDeps , referenced : TypeParamRef ): ReverseDeps =
243
247
val entry = deps(referenced)
244
248
val prev = if null == entry then SimpleIdentitySet .empty else entry
245
- val now = if add then prev + tvar else prev - tvar
249
+ val now = if add then prev + srcParam else prev - srcParam
246
250
deps.updated(referenced, now)
247
251
248
252
def traverse (t : Type ) = t match
249
- case tv : TypeVar =>
250
- val inst = tv.instanceOpt
251
- if inst.exists then traverse(inst)
252
- else
253
- if variance >= 0 then coDeps = update(coDeps, tv)
254
- if variance <= 0 then contraDeps = update(contraDeps, tv)
255
253
case param : TypeParamRef =>
256
- traverse(typeVarOfParam(param))
254
+ if contains(param) then
255
+ if variance >= 0 then coDeps = update(coDeps, param)
256
+ if variance <= 0 then contraDeps = update(contraDeps, param)
257
257
case tp : LazyRef if ! tp.completed =>
258
- case _ =>
259
- traverseChildren(t)
258
+ case _ => traverseChildren(t)
259
+ end Adjuster
260
260
261
261
/** Adjust dependencies to account for the delta of previous entry `prevEntry`
262
262
* and new bound `entry` for the type variable `tvar`.
263
263
*/
264
- def adjustDeps (entry : Type | Null , prevEntry : Type | Null , tvar : Type | Null )(using Context ): this .type =
265
- tvar match
266
- case tvar : TypeVar =>
267
- val adjuster = new Adjuster (tvar)
268
-
269
- /** Adjust reverse depemdencies of all type variables referenced by `bound`
270
- * @param isLower `bound` is a lower bound
271
- * @param add if true, add referenced variables to dependencoes, otherwise drop them.
272
- */
273
- def adjustReferenced (bound : Type , isLower : Boolean , add : Boolean ) =
274
- adjuster.variance = if isLower then 1 else - 1
275
- adjuster.add = add
276
- adjuster.traverse(bound)
277
-
278
- /** Use an optimized strategy to adjust dependencies to account for the delta
279
- * of previous bound `prevBound` and new bound `bound`: If `prevBound` is some
280
- * and/or prefix of `bound`, just add the new parts of `bound`.
281
- * @param isLower `bound` and `prevBound` are lower bounds
282
- */
283
- def adjustDelta (bound : Type , prevBound : Type , isLower : Boolean ): Boolean =
284
- if bound eq prevBound then true
285
- else bound match
286
- case bound : AndOrType =>
287
- adjustDelta(bound.tp1, prevBound, isLower) && {
288
- adjustReferenced(bound.tp2, isLower, add = true )
289
- true
290
- }
291
- case _ => false
292
-
293
- /** Adjust dependencies to account for the delta of previous bound `prevBound`
294
- * and new bound `bound`.
295
- * @param isLower `bound` and `prevBound` are lower bounds
296
- */
297
- def adjustBounds (bound : Type , prevBound : Type , isLower : Boolean ) =
298
- if ! adjustDelta(bound, prevBound, isLower) then
299
- adjustReferenced(prevBound, isLower, add = false )
300
- adjustReferenced(bound, isLower, add = true )
301
-
302
- entry match
303
- case TypeBounds (lo, hi) =>
304
- prevEntry match
305
- case TypeBounds (plo, phi) =>
306
- adjustBounds(lo, plo, isLower = true )
307
- adjustBounds(hi, phi, isLower = false )
308
- case _ =>
309
- adjustReferenced(lo, isLower = true , add = true )
310
- adjustReferenced(hi, isLower = false , add = true )
264
+ def adjustDeps (entry : Type | Null , prevEntry : Type | Null , srcParam : TypeParamRef )(using Context ): this .type =
265
+ val adjuster = new Adjuster (srcParam)
266
+
267
+ /** Adjust reverse depemdencies of all type parameters referenced by `bound`
268
+ * @param isLower `bound` is a lower bound
269
+ * @param add if true, add referenced variables to dependencoes, otherwise drop them.
270
+ */
271
+ def adjustReferenced (bound : Type , isLower : Boolean , add : Boolean ) =
272
+ adjuster.variance = if isLower then 1 else - 1
273
+ adjuster.add = add
274
+ adjuster.traverse(bound)
275
+
276
+ /** Use an optimized strategy to adjust dependencies to account for the delta
277
+ * of previous bound `prevBound` and new bound `bound`: If `prevBound` is some
278
+ * and/or prefix of `bound`, just add the new parts of `bound`.
279
+ * @param isLower `bound` and `prevBound` are lower bounds
280
+ */
281
+ def adjustDelta (bound : Type , prevBound : Type , isLower : Boolean ): Boolean =
282
+ if bound eq prevBound then true
283
+ else bound match
284
+ case bound : AndOrType =>
285
+ adjustDelta(bound.tp1, prevBound, isLower) && {
286
+ adjustReferenced(bound.tp2, isLower, add = true )
287
+ true
288
+ }
289
+ case _ => false
290
+
291
+ /** Adjust dependencies to account for the delta of previous bound `prevBound`
292
+ * and new bound `bound`.
293
+ * @param isLower `bound` and `prevBound` are lower bounds
294
+ */
295
+ def adjustBounds (bound : Type , prevBound : Type , isLower : Boolean ) =
296
+ if ! adjustDelta(bound, prevBound, isLower) then
297
+ adjustReferenced(prevBound, isLower, add = false )
298
+ adjustReferenced(bound, isLower, add = true )
299
+
300
+ entry match
301
+ case TypeBounds (lo, hi) =>
302
+ prevEntry match
303
+ case TypeBounds (plo, phi) =>
304
+ adjustBounds(lo, plo, isLower = true )
305
+ adjustBounds(hi, phi, isLower = false )
311
306
case _ =>
312
- prevEntry match
313
- case TypeBounds (plo, phi) =>
314
- adjustReferenced(plo, isLower = true , add = false )
315
- adjustReferenced(phi, isLower = false , add = false )
316
- case _ =>
317
- dropDeps(tvar)
307
+ adjustReferenced(lo, isLower = true , add = true )
308
+ adjustReferenced(hi, isLower = false , add = true )
318
309
case _ =>
310
+ prevEntry match
311
+ case TypeBounds (plo, phi) =>
312
+ adjustReferenced(plo, isLower = true , add = false )
313
+ adjustReferenced(phi, isLower = false , add = false )
314
+ case _ =>
315
+ dropDeps(srcParam)
319
316
this
320
317
end adjustDeps
321
318
322
319
/** Adjust dependencies to account for adding or dropping `entries` to the
323
320
* constraint.
324
321
* @param add if true, entries is added, otherwise it is dropped
325
322
*/
326
- def adjustDeps (entries : Array [Type ], add : Boolean )(using Context ): this .type =
323
+ def adjustDeps (poly : TypeLambda , entries : Array [Type ], add : Boolean )(using Context ): this .type =
327
324
for n <- 0 until paramCount(entries) do
328
325
if add
329
- then adjustDeps(entries(n), NoType , typeVar(entries, n))
330
- else adjustDeps(NoType , entries(n), typeVar(entries, n))
326
+ then adjustDeps(entries(n), NoType , poly.paramRefs( n))
327
+ else adjustDeps(NoType , entries(n), poly.paramRefs( n))
331
328
this
332
329
333
330
/** If `tp` is a type variable, remove all its reverse dependencies */
334
- def dropDeps (tp : Type )(using Context ): Unit = tp match
335
- case tv : TypeVar =>
336
- coDeps = coDeps.remove(tv)
337
- contraDeps = contraDeps.remove(tv)
338
- case _ =>
331
+ def dropDeps (param : TypeParamRef )(using Context ): Unit =
332
+ coDeps = coDeps.remove(param)
333
+ contraDeps = contraDeps.remove(param)
339
334
340
335
/** A string representing the two depenecy maps */
341
336
def depsToString (using Context ): String =
342
- def depsStr (deps : SimpleIdentityMap [ TypeVar , TypeVars ] ): String =
343
- def depStr (tv : TypeVar ) = i " $tv --> ${deps(tv ).nn.toList}%, % "
337
+ def depsStr (deps : ReverseDeps ): String =
338
+ def depStr (param : TypeParamRef ) = i " $param --> ${deps(param ).nn.toList}%, % "
344
339
if deps.isEmpty then " " else i " \n ${deps.toList.map((k, v) => depStr(k))}% \n % "
345
340
i " co-deps: ${depsStr(coDeps)}\n contra-deps: ${depsStr(contraDeps)}\n "
346
341
@@ -411,7 +406,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
411
406
tvars.copyToArray(entries1, nparams)
412
407
newConstraint(boundsMap = this .boundsMap.updated(poly, entries1))
413
408
.init(poly)
414
- .adjustDeps(entries1, add = true )
409
+ .adjustDeps(poly, entries1, add = true )
415
410
}
416
411
417
412
/** Split dependent parameters off the bounds for parameters in `poly`.
@@ -558,7 +553,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
558
553
private def updateEntry (current : This , param : TypeParamRef , tp : Type )(using Context ): This = {
559
554
if Config .checkNoWildcardsInConstraint then assert(! tp.containsWildcardTypes)
560
555
var current1 = boundsLens.update(this , current, param, tp)
561
- current1.adjustDeps(tp, current.entry(param), typeVarOfParam( param) )
556
+ current1.adjustDeps(tp, current.entry(param), param)
562
557
tp match {
563
558
case TypeBounds (lo, hi) =>
564
559
for p <- dependentParams(lo, isUpper = false ) do
@@ -601,12 +596,12 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
601
596
current = boundsLens.map(this , current, p, i,
602
597
entry =>
603
598
val newEntry = replaceParam(entry, p, i)
604
- adjustDeps(newEntry, entry, typeVar( this .boundsMap(p).nn, i))
599
+ adjustDeps(newEntry, entry, p.paramRefs( i))
605
600
newEntry)
606
601
current = lowerLens.map(this , current, p, i, removeParam)
607
602
current = upperLens.map(this , current, p, i, removeParam)
608
603
}
609
- current.dropDeps(typeVarOfParam( param) )
604
+ current.dropDeps(param)
610
605
current.checkWellFormed()
611
606
end replace
612
607
@@ -620,7 +615,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
620
615
}
621
616
val hardVars1 = pt.paramRefs.foldLeft(hardVars)((hvs, param) => hvs - typeVarOfParam(param))
622
617
newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap), hardVars1)
623
- .adjustDeps(boundsMap(pt).nn, add = false )
618
+ .adjustDeps(pt, boundsMap(pt).nn, add = false )
624
619
.checkWellFormed()
625
620
}
626
621
@@ -749,11 +744,11 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
749
744
s " cyclic bound for $param: ${inst.show} in ${this .show}" )
750
745
}
751
746
if Config .checkConstraintDeps then
752
- def checkDeps (deps : TypeVarDeps ) =
747
+ def checkDeps (deps : ReverseDeps ) = () /*
753
748
deps.foreachBinding { (tv, tvs) =>
754
749
for tv1 <- tvs do
755
750
assert(!tv1.instanceOpt.exists, i"$this")
756
- }
751
+ }*/
757
752
checkDeps(coDeps)
758
753
checkDeps(contraDeps)
759
754
this
0 commit comments