@@ -10,8 +10,7 @@ import printing.Texts._
1010import config .Config
1111import config .Printers .constr
1212import reflect .ClassTag
13- import Constraint .TypeVarDeps
14- import NameKinds .DepParamName
13+ import Constraint .ReverseDeps
1514import annotation .tailrec
1615import annotation .internal .sharable
1716import cc .{CapturingType , derivedCapturingType }
@@ -223,124 +222,120 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
223222 if tvar == null then NoType
224223 else tvar
225224
226- // ------------- TypeVar dependencies -----------------------------------
225+ // ------------- Type parameter dependencies ----- -----------------------------------
227226
228- var coDeps, contraDeps : TypeVarDeps = SimpleIdentityMap .empty
227+ var coDeps, contraDeps : ReverseDeps = SimpleIdentityMap .empty
229228
230229 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)))
230+ def origin (tv : TypeVar ) =
231+ assert(! tv.isInstantiated)
232+ tv.origin
233+ val param = origin(tv)
234+ val excluded = except.map(origin)
235+ val qualifies : TypeParamRef => Boolean = ! excluded.contains(_)
236+ def test (deps : ReverseDeps , lens : ConstraintLens [List [TypeParamRef ]]) =
237+ val depending = deps(param)
238+ null != depending && depending.exists(qualifies)
239+ || lens(this , tv.origin.binder, tv.origin.paramNum).exists(qualifies)
236240 // .showing(i"outer depends on $tv with ${tvdeps.toList}%, % = $result")
237241 if co then test(coDeps, upperLens) else test(contraDeps, lowerLens)
238242
239- private class Adjuster (tvar : TypeVar )(using Context ) extends TypeTraverser :
243+ private class Adjuster (srcParam : TypeParamRef )(using Context ) extends TypeTraverser :
240244 var add : Boolean = compiletime.uninitialized
241245
242- def update (deps : TypeVarDeps , referenced : TypeVar ): TypeVarDeps =
246+ def update (deps : ReverseDeps , referenced : TypeParamRef ): ReverseDeps =
243247 val entry = deps(referenced)
244248 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
246250 deps.updated(referenced, now)
247251
248252 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)
255253 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)
257257 case tp : LazyRef if ! tp.completed =>
258- case _ =>
259- traverseChildren(t)
258+ case _ => traverseChildren(t)
259+ end Adjuster
260260
261261 /** Adjust dependencies to account for the delta of previous entry `prevEntry`
262- * and new bound `entry` for the type variable `tvar `.
262+ * and new bound `entry` for the type parameter `srcParam `.
263263 */
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 dependencies 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 )
311306 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 )
318309 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)
319316 this
320317 end adjustDeps
321318
322- /** Adjust dependencies to account for adding or dropping `entries` to the
323- * constraint .
319+ /** Adjust dependencies to account for adding or dropping all `entries` associated
320+ * with `poly` .
324321 * @param add if true, entries is added, otherwise it is dropped
325322 */
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 =
327324 for n <- 0 until paramCount(entries) do
328325 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))
331328 this
332329
333- /** 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 _ =>
330+ /** Remove all reverse dependencies of `param` */
331+ def dropDeps (param : TypeParamRef )(using Context ): Unit =
332+ coDeps = coDeps.remove(param)
333+ contraDeps = contraDeps.remove(param)
339334
340335 /** A string representing the two depenecy maps */
341336 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}%, % "
344339 if deps.isEmpty then " " else i " \n ${deps.toList.map((k, v) => depStr(k))}% \n % "
345340 i " co-deps: ${depsStr(coDeps)}\n contra-deps: ${depsStr(contraDeps)}\n "
346341
@@ -411,7 +406,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
411406 tvars.copyToArray(entries1, nparams)
412407 newConstraint(boundsMap = this .boundsMap.updated(poly, entries1))
413408 .init(poly)
414- .adjustDeps(entries1, add = true )
409+ .adjustDeps(poly, entries1, add = true )
415410 }
416411
417412 /** Split dependent parameters off the bounds for parameters in `poly`.
@@ -558,7 +553,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
558553 private def updateEntry (current : This , param : TypeParamRef , tp : Type )(using Context ): This = {
559554 if Config .checkNoWildcardsInConstraint then assert(! tp.containsWildcardTypes)
560555 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)
562557 tp match {
563558 case TypeBounds (lo, hi) =>
564559 for p <- dependentParams(lo, isUpper = false ) do
@@ -594,19 +589,22 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
594589
595590 def removeParam (ps : List [TypeParamRef ]) = ps.filterConserve(param ne _)
596591
597- def replaceParam (tp : Type , atPoly : TypeLambda , atIdx : Int ): Type =
598- current.ensureNonCyclic(atPoly.paramRefs(atIdx), tp.substParam(param, replacement))
592+ def replaceParam (entry : Type , atPoly : TypeLambda , atIdx : Int ): Type =
593+ val pref = atPoly.paramRefs(atIdx)
594+ val newEntry = current.ensureNonCyclic(pref, entry.substParam(param, replacement))
595+ adjustDeps(newEntry, entry, pref)
596+ newEntry
599597
600598 current.foreachParam { (p, i) =>
601599 current = boundsLens.map(this , current, p, i,
602600 entry =>
603601 val newEntry = replaceParam(entry, p, i)
604- adjustDeps(newEntry, entry, typeVar( this .boundsMap(p).nn, i))
602+ adjustDeps(newEntry, entry, p.paramRefs( i))
605603 newEntry)
606604 current = lowerLens.map(this , current, p, i, removeParam)
607605 current = upperLens.map(this , current, p, i, removeParam)
608606 }
609- current.dropDeps(typeVarOfParam( param) )
607+ current.dropDeps(param)
610608 current.checkWellFormed()
611609 end replace
612610
@@ -620,7 +618,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
620618 }
621619 val hardVars1 = pt.paramRefs.foldLeft(hardVars)((hvs, param) => hvs - typeVarOfParam(param))
622620 newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap), hardVars1)
623- .adjustDeps(boundsMap(pt).nn, add = false )
621+ .adjustDeps(pt, boundsMap(pt).nn, add = false )
624622 .checkWellFormed()
625623 }
626624
@@ -749,11 +747,11 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
749747 s " cyclic bound for $param: ${inst.show} in ${this .show}" )
750748 }
751749 if Config .checkConstraintDeps then
752- def checkDeps (deps : TypeVarDeps ) =
750+ def checkDeps (deps : ReverseDeps ) = () /*
753751 deps.foreachBinding { (tv, tvs) =>
754752 for tv1 <- tvs do
755753 assert(!tv1.instanceOpt.exists, i"$this")
756- }
754+ }*/
757755 checkDeps(coDeps)
758756 checkDeps(contraDeps)
759757 this
0 commit comments