@@ -11,6 +11,7 @@ import config.Config
1111import config .Printers .constr
1212import reflect .ClassTag
1313import Constraint .ReverseDeps
14+ import Substituters .SubstParamMap
1415import annotation .tailrec
1516import annotation .internal .sharable
1617import cc .{CapturingType , derivedCapturingType }
@@ -37,7 +38,7 @@ object OrderingConstraint {
3738 }
3839
3940 /** The `current` constraint but with the entry for `param` updated to `entry`.
40- * `current` is used linearly. If it is different from `prev` it is
41+ * `current` is used linearly. If it is different from `prev` then `current` is
4142 * known to be dead after the call. Hence it is OK to update destructively
4243 * parts of `current` which are not shared by `prev`.
4344 */
@@ -133,6 +134,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
133134 private val lowerMap : ParamOrdering ,
134135 private val upperMap : ParamOrdering ,
135136 private val hardVars : TypeVars ) extends Constraint {
137+ thisConstraint =>
136138
137139 import UnificationDirection .*
138140
@@ -243,7 +245,9 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
243245 // .showing(i"outer depends on $tv with ${tvdeps.toList}%, % = $result")
244246 if co then test(coDeps, upperLens) else test(contraDeps, lowerLens)
245247
246- private class Adjuster (srcParam : TypeParamRef )(using Context ) extends TypeTraverser :
248+ private class Adjuster (srcParam : TypeParamRef )(using Context )
249+ extends TypeTraverser , ConstraintAwareTraversal :
250+
247251 var add : Boolean = compiletime.uninitialized
248252 val seen = util.HashSet [LazyRef ]()
249253
@@ -411,7 +415,6 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
411415 tvars.copyToArray(entries1, nparams)
412416 newConstraint(boundsMap = this .boundsMap.updated(poly, entries1))
413417 .init(poly)
414- .adjustDeps(poly, entries1, add = true )
415418 }
416419
417420 /** Split dependent parameters off the bounds for parameters in `poly`.
@@ -433,7 +436,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
433436 todos.dropInPlace(1 )
434437 i += 1
435438 }
436- current.checkWellFormed()
439+ current.adjustDeps(poly, current.boundsMap(poly).nn, add = true )
440+ .checkWellFormed()
437441 }
438442
439443// ---------- Updates ------------------------------------------------------------
@@ -591,30 +595,33 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
591595 if param == replacement then this .checkWellFormed()
592596 else
593597 assert(replacement.isValueTypeOrLambda)
594- var current =
595- if isRemovable(param.binder) then remove(param.binder)
596- else updateEntry(this , param, replacement)
597598
598- def removeParam ( ps : List [ TypeParamRef ]) = ps.filterConserve (param ne _ )
599+ val droppedTypeVar = typeVarOfParam (param)
599600
600- def replaceParam (entry : Type , atPoly : TypeLambda , atIdx : Int ): Type =
601- val pref = atPoly.paramRefs(atIdx)
602- val newEntry = current.ensureNonCyclic(pref, entry.substParam(param, replacement))
603- adjustDeps(newEntry, entry, pref)
604- newEntry
601+ // println(i"replace $param, $droppedTypeVar with $replacement in $this")
602+ val dropTypeVar = new TypeMap :
603+ override def apply (t : Type ): Type =
604+ if t.exists && (t eq droppedTypeVar) then param else mapOver(t)
605605
606+ var current = this
607+
608+ def removeParam (ps : List [TypeParamRef ]) = ps.filterConserve(param ne _)
606609 for lo <- lower(param) do
607610 current = upperLens.map(this , current, lo, removeParam)
608611 for hi <- upper(param) do
609612 current = lowerLens.map(this , current, hi, removeParam)
610613
611614 current.foreachParam { (p, i) =>
612- current = boundsLens.map( this , current, p, i,
613- entry =>
614- val newEntry = replaceParam( entry, p, i )
615- adjustDeps(newEntry, entry, p.paramRefs(i ))
616- newEntry)
615+ val other = p.paramRefs(i)
616+ if other != param then
617+ val oldEntry = current. entry(other )
618+ val newEntry = current.ensureNonCyclic(other, oldEntry.substParam(param, replacement ))
619+ current = updateEntryNoOrdering(current, other, newEntry, dropTypeVar(oldEntry) )
617620 }
621+
622+ current =
623+ if isRemovable(param.binder) then current.remove(param.binder)
624+ else updateEntry(current, param, replacement)
618625 current.dropDeps(param)
619626 current.checkWellFormed()
620627 end replace
0 commit comments