diff options
author | Martin Odersky <odersky@gmail.com> | 2013-10-24 13:27:14 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-10-24 13:27:14 +0200 |
commit | 3f5af18620f5274fefe9683542fd4f02ec099dfd (patch) | |
tree | 199424ffca61cee48d33a2b432cffea85b077219 /src | |
parent | 87a079d4ac59925a1da31071b35a5ef05764700e (diff) | |
download | dotty-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.scala | 10 |
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 |