@@ -389,7 +389,7 @@ trait Inferencing { this: Typer =>
389
389
if ((ownedVars ne locked) && ! ownedVars.isEmpty) {
390
390
val qualifying = ownedVars -- locked
391
391
if (! qualifying.isEmpty) {
392
- typr.println(i " interpolate $tree: ${tree.tpe.widen} in $state, owned vars = ${state.ownedVars.toList}%, %, previous = ${locked.toList}%, % / ${state.constraint}" )
392
+ typr.println(i " interpolate $tree: ${tree.tpe.widen} in $state, owned vars = ${state.ownedVars.toList}%, %, qualifying = ${qualifying.toList} %, %, previous = ${locked.toList}%, % / ${state.constraint}" )
393
393
val resultAlreadyConstrained =
394
394
tree.isInstanceOf [Apply ] || tree.tpe.isInstanceOf [MethodOrPoly ]
395
395
if (! resultAlreadyConstrained)
@@ -421,22 +421,40 @@ trait Inferencing { this: Typer =>
421
421
// val y: List[List[String]] = List(List(1))
422
422
val hasUnreportedErrors = state.reporter.hasUnreportedErrors
423
423
def constraint = state.constraint
424
+ type InstantiateQueue = mutable.ListBuffer [(TypeVar , Boolean )]
425
+ val toInstantiate = new InstantiateQueue
424
426
for (tvar <- qualifying)
425
427
if (! tvar.isInstantiated && state.constraint.contains(tvar)) {
426
428
// Needs to be checked again, since previous interpolations could already have
427
429
// instantiated `tvar` through unification.
428
430
val v = vs(tvar)
429
431
if (v == null ) {
430
432
typr.println(i " interpolate non-occurring $tvar in $state in $tree: $tp, fromBelow = ${tvar.hasLowerBound}, $constraint" )
431
- tvar.instantiate(fromBelow = tvar.hasLowerBound)
433
+ toInstantiate += (( tvar, tvar .hasLowerBound) )
432
434
}
433
435
else if (! hasUnreportedErrors)
434
436
if (v.intValue != 0 ) {
435
437
typr.println(i " interpolate $tvar in $state in $tree: $tp, fromBelow = ${v.intValue == 1 }, $constraint" )
436
- tvar.instantiate(fromBelow = v.intValue == 1 )
438
+ toInstantiate += ((tvar, v.intValue == 1 ) )
437
439
}
438
440
else typr.println(i " no interpolation for nonvariant $tvar in $state" )
439
441
}
442
+
443
+ def doInstantiate (buf : InstantiateQueue ): Unit =
444
+ if buf.nonEmpty then
445
+ val suspended = new InstantiateQueue
446
+ while buf.nonEmpty do
447
+ val first @ (tvar, fromBelow) = buf.head
448
+ buf.dropInPlace(1 )
449
+ val suspend = buf.exists{ (following, _) =>
450
+ if fromBelow then constraint.isLess(following.origin, tvar.origin)
451
+ else constraint.isLess(following.origin, tvar.origin)
452
+ }
453
+ if suspend then suspended += first
454
+ else tvar.instantiate(fromBelow)
455
+ doInstantiate(suspended)
456
+ end doInstantiate
457
+ doInstantiate(toInstantiate)
440
458
}
441
459
}
442
460
tree
0 commit comments