@@ -16,6 +16,7 @@ import reporting._
16
16
import collection .mutable
17
17
18
18
import scala .annotation .internal .sharable
19
+ import dotty .tools .dotc .util .SimpleIdentitySet
19
20
20
21
object Inferencing {
21
22
@@ -619,7 +620,7 @@ trait Inferencing { this: Typer =>
619
620
if state.reporter.hasUnreportedErrors then return tree
620
621
621
622
def constraint = state.constraint
622
- type InstantiateQueue = mutable.ListBuffer [(TypeVar , Boolean )]
623
+ type InstantiateQueue = mutable.ListBuffer [(TypeVar , Int )]
623
624
val toInstantiate = new InstantiateQueue
624
625
for tvar <- qualifying do
625
626
if ! tvar.isInstantiated && constraint.contains(tvar) && tvar.nestingLevel >= ctx.nestingLevel then
@@ -637,18 +638,16 @@ trait Inferencing { this: Typer =>
637
638
// instantiate it in the direction corresponding to the
638
639
// original variable which might be further constrained later.
639
640
// Otherwise, we simply rely on `hasLowerBound`.
640
- val name = tvar.origin.paramName
641
- val fromBelow =
642
- if name.is(AvoidNameKind .UpperBound ) then true
643
- else if name.is(AvoidNameKind .LowerBound ) then false
644
- else if constraint.outerDependsCovariantlyOn(tvar) then true
645
- else if constraint.outerDependsContravariantlyOn(tvar) then false
646
- else tvar.hasLowerBound
647
- typr.println(i " interpolate non-occurring $tvar in $state in $tree: $tp, fromBelow = $fromBelow, $constraint" )
648
- toInstantiate += ((tvar, fromBelow))
641
+ // val name = tvar.origin.paramName
642
+ // val fromBelow =
643
+ // if name.is(AvoidNameKind.UpperBound) then true
644
+ // else if name.is(AvoidNameKind.LowerBound) then false
645
+ // else if constraint.outerDependsCovariantlyOn(tvar) then true
646
+ // else if constraint.outerDependsContravariantlyOn(tvar) then false
647
+ // else tvar.hasLowerBound
648
+ toInstantiate += ((tvar, 0 ))
649
649
else if v.intValue != 0 then
650
- typr.println(i " interpolate $tvar in $state in $tree: $tp, fromBelow = ${v.intValue == 1 }, $constraint" )
651
- toInstantiate += ((tvar, v.intValue == 1 ))
650
+ toInstantiate += ((tvar, v.intValue))
652
651
else comparing(cmp =>
653
652
if ! cmp.levelOK(tvar.nestingLevel, ctx.nestingLevel) then
654
653
// Invariant: The type of a tree whose enclosing scope is level
@@ -689,10 +688,38 @@ trait Inferencing { this: Typer =>
689
688
* V2 := V3, O2 := O3
690
689
*/
691
690
def doInstantiate (buf : InstantiateQueue ): Unit =
691
+ val varsToInstantiate = buf.foldLeft(SimpleIdentitySet .empty: TypeVars ) {
692
+ case (tvs, (tv, _)) => tvs + tv
693
+ }
692
694
if buf.nonEmpty then
693
695
val suspended = new InstantiateQueue
694
696
while buf.nonEmpty do
695
- val first @ (tvar, fromBelow) = buf.head
697
+ val first @ (tvar, v) = buf.head
698
+ val fromBelow =
699
+ if v == 0 then
700
+ val aboveOK = ! constraint.dependsOn(tvar, varsToInstantiate, co = true )
701
+ val belowOK = ! constraint.dependsOn(tvar, varsToInstantiate, co = false )
702
+ val now =
703
+ if aboveOK == belowOK then tvar.hasLowerBound
704
+ else belowOK
705
+ /*
706
+ val was =
707
+ val name = tvar.origin.paramName
708
+ val depCo = constraint.outerDependsCovariantlyOn(tvar)
709
+ val depContra = constraint.outerDependsContravariantlyOn(tvar)
710
+ if name.is(AvoidNameKind.UpperBound) then true
711
+ else if name.is(AvoidNameKind.LowerBound) then false
712
+ else if constraint.outerDependsCovariantlyOn(tvar) then true
713
+ else if constraint.outerDependsContravariantlyOn(tvar) then false
714
+ else tvar.hasLowerBound
715
+ if now != was then
716
+ println(i"diff for $tvar, was $was, aboveOK = $aboveOK, belowOK = $belowOK, depCo = $depCo, depContra = $depContra")
717
+ */
718
+ now
719
+ else
720
+ v == 1
721
+ typr.println(
722
+ i " interpolate ${if v == 0 then " non-occurring" else " " } $tvar in $state in $tree: $tp, fromBelow = $fromBelow, $constraint" )
696
723
buf.dropInPlace(1 )
697
724
if ! tvar.isInstantiated then
698
725
val suspend = buf.exists{ (following, _) =>
0 commit comments