@@ -640,6 +640,31 @@ trait Inferencing { this: Typer =>
640
640
typr.println(i " no interpolation for nonvariant $tvar in $state" )
641
641
)
642
642
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
+
643
668
/** Instantiate all type variables in `buf` in the indicated directions.
644
669
* If a type variable A is instantiated from below, and there is another
645
670
* type variable B in `buf` that is known to be smaller than A, wait and
@@ -669,38 +694,45 @@ trait Inferencing { this: Typer =>
669
694
*
670
695
* V2 := V3, O2 := O3
671
696
*/
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 =>
680
701
val fromBelow =
681
702
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" )
684
707
if aboveOK == belowOK then tvar.hasLowerBound
685
708
else belowOK
686
709
else
687
710
v == 1
688
711
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)
697
720
}
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))
702
729
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)
704
736
}
705
737
}
706
738
tree
0 commit comments