aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-10-24 13:27:14 +0200
committerMartin Odersky <odersky@gmail.com>2013-10-24 13:27:14 +0200
commit3f5af18620f5274fefe9683542fd4f02ec099dfd (patch)
tree199424ffca61cee48d33a2b432cffea85b077219 /src
parent87a079d4ac59925a1da31071b35a5ef05764700e (diff)
downloaddotty-3f5af18620f5274fefe9683542fd4f02ec099dfd.tar.gz
dotty-3f5af18620f5274fefe9683542fd4f02ec099dfd.tar.bz2
dotty-3f5af18620f5274fefe9683542fd4f02ec099dfd.zip
Fixed premature stopping of type variable instantiations.
When type variables are instantiated (either by interpolation or forcing) the result can contain references to otrher type variables that need to be instantiated in turn.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index cbce206ef..b1236840f 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -11,6 +11,7 @@ import util.Positions._
import util.Stats
import Decorators._
import ErrorReporting.{errorType, InfoString}
+import collection.mutable.ListBuffer
object Inferencing {
@@ -138,7 +139,7 @@ object Inferencing {
case tvar: TypeVar if forceIt && !tvar.isInstantiated =>
val inst = tvar.instantiate(fromBelow = true)
println(i"forced instantiation of ${tvar.origin} = $inst")
- inst != defn.NothingType && inst != defn.NullType
+ inst != defn.NothingType && inst != defn.NullType && traverse(inst)
case _ =>
true
}
@@ -198,22 +199,27 @@ object Inferencing {
* approximate it by its lower bound. Otherwise, if it appears contravariantly
* in type `tp` approximate it by its upper bound.
*/
- def interpolateUndetVars(tp: Type, pos: Position): Unit = Stats.track("interpolateUndetVars") {
+ def interpolateUndetVars(tp: Type, pos: Position, direction: Int = 1): Unit = Stats.track("interpolateUndetVars") {
val vs = tp.variances(tvar =>
(ctx.typerState.undetVars contains tvar) && (pos contains tvar.pos))
+ var todo = new ListBuffer[() => Unit]
for ((tvar, v) <- vs)
if (v == 1) {
println(s"interpolate covariant ${tvar.show} in ${tp.show}")
tvar.instantiate(fromBelow = true)
+ todo += (() => interpolateUndetVars(tvar.instanceOpt, pos, direction))
}
else if (v == -1) {
println(s"interpolate contrvariant ${tvar.show} in ${tp.show}")
tvar.instantiate(fromBelow = false)
+ todo += (() => interpolateUndetVars(tvar.instanceOpt, pos, -direction))
}
for (tvar <- ctx.typerState.undetVars if (pos contains tvar.pos) && !(vs contains tvar)) {
println(s"interpolate non-occurring ${tvar.show} in ${tp.show}")
tvar.instantiate(fromBelow = true)
+ todo += (() => interpolateUndetVars(tvar.instanceOpt, pos, direction))
}
+ todo foreach (_())
}
/** Instantiate undetermined type variables to that type `tp` is