@@ -640,6 +640,31 @@ trait Inferencing { this: Typer =>
640640 typr.println(i " no interpolation for nonvariant $tvar in $state" )
641641 )
642642
643+ def typeVarsIn (xs : collection.Seq [(TypeVar , Int )]): TypeVars =
644+ xs.foldLeft(SimpleIdentitySet .empty: TypeVars )((tvs, tvi) => tvs + tvi._1)
645+
646+ def filterByDeps (tvs0 : List [(TypeVar , Int )]): List [(TypeVar , Int )] = {
647+ val excluded = typeVarsIn(tvs0)
648+ def step (tvs : List [(TypeVar , Int )]): List [(TypeVar , Int )] = tvs match
649+ case tvs @ (hd @ (tvar, v)) :: tvs1 =>
650+ def aboveOK = ! constraint.dependsOn(tvar, excluded, co = true )
651+ def belowOK = ! constraint.dependsOn(tvar, excluded, co = false )
652+ if v == 0 && ! aboveOK then
653+ step((tvar, 1 ) :: tvs1)
654+ else if v == 0 && ! belowOK then
655+ step((tvar, - 1 ) :: tvs1)
656+ else if v == - 1 && ! aboveOK || v == 1 && ! belowOK then
657+ println(i " drop $tvar, $v in $tp, $pt, qualifying = ${qualifying.toList}, tvs0 = ${tvs0.toList}%, %, excluded = ${excluded.toList}, $constraint" )
658+ step(tvs1)
659+ else
660+ tvs.derivedCons(hd, step(tvs1))
661+ case Nil =>
662+ Nil
663+ val tvs1 = step(tvs0)
664+ if tvs1 eq tvs0 then tvs1 else filterByDeps(tvs1)
665+ }// .showing(i"filter $tvs0 in $constraint = $result")
666+ end filterByDeps
667+
643668 /** Instantiate all type variables in `buf` in the indicated directions.
644669 * If a type variable A is instantiated from below, and there is another
645670 * type variable B in `buf` that is known to be smaller than A, wait and
@@ -669,38 +694,45 @@ trait Inferencing { this: Typer =>
669694 *
670695 * V2 := V3, O2 := O3
671696 */
672- def doInstantiate (buf : InstantiateQueue ): Unit =
673- val varsToInstantiate = buf.foldLeft(SimpleIdentitySet .empty: TypeVars ) {
674- case (tvs, (tv, _)) => tvs + tv
675- }
676- if buf.nonEmpty then
677- val suspended = new InstantiateQueue
678- while buf.nonEmpty do
679- val first @ (tvar, v) = buf.head
697+ def doInstantiate (tvs : List [(TypeVar , Int )]): Unit =
698+ def excluded = typeVarsIn(tvs)
699+ def tryInstantiate (tvs : List [(TypeVar , Int )]): List [(TypeVar , Int )] = tvs match
700+ case (hd @ (tvar, v)) :: tvs1 =>
680701 val fromBelow =
681702 if v == 0 then
682- val aboveOK = ! constraint.dependsOn(tvar, varsToInstantiate, co = true )
683- val belowOK = ! constraint.dependsOn(tvar, varsToInstantiate, co = false )
703+ val aboveOK = true // !constraint.dependsOn(tvar, excluded, co = true, track = true)
704+ val belowOK = true // !constraint.dependsOn(tvar, excluded, co = false, track = true)
705+ assert(aboveOK, i " $tvar, excluded = ${excluded.toList}, $constraint" )
706+ assert(belowOK, i " $tvar, excluded = ${excluded.toList}, $constraint" )
684707 if aboveOK == belowOK then tvar.hasLowerBound
685708 else belowOK
686709 else
687710 v == 1
688711 typr.println(
689- i " interpolate ${if v == 0 then " non-occurring" else " " } $tvar in $state in $tree: $tp, fromBelow = $fromBelow, $constraint" )
690- buf.dropInPlace( 1 )
691- if ! tvar.isInstantiated then
692- val suspend = buf.exists{ (following, _) =>
693- if fromBelow then
694- constraint.isLess(following.origin, tvar.origin)
695- else
696- constraint.isLess(tvar.origin, following.origin)
712+ i " interpolate ${if v == 0 then " non-occurring" else " " } $tvar in $state in $tree: $tp, fromBelow = $fromBelow, $constraint" )
713+ if tvar.isInstantiated then
714+ tryInstantiate(tvs1)
715+ else
716+ val suspend = tvs1.exists{ (following, _) =>
717+ if fromBelow
718+ then constraint.isLess(following.origin, tvar.origin)
719+ else constraint.isLess(tvar.origin, following.origin)
697720 }
698- if suspend then suspended += first else tvar.instantiate(fromBelow)
699- end if
700- end while
701- doInstantiate(suspended)
721+ if suspend then
722+ typr.println(i " suspended: $hd" )
723+ hd :: tryInstantiate(tvs1)
724+ else
725+ tvar.instantiate(fromBelow)
726+ tryInstantiate(tvs1)
727+ case Nil => Nil
728+ if tvs.nonEmpty then doInstantiate(tryInstantiate(tvs))
702729 end doInstantiate
703- doInstantiate(toInstantiate)
730+ val toInst = toInstantiate.toList
731+ if toInst.nonEmpty then
732+ typr.println(i " interpolating $toInst for $tp/ $pt in $constraint" )
733+ val filtered = filterByDeps(toInst)
734+ typr.println(i " filtered $filtered" )
735+ doInstantiate(filtered)
704736 }
705737 }
706738 tree
0 commit comments