From 3f5af18620f5274fefe9683542fd4f02ec099dfd Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 24 Oct 2013 13:27:14 +0200 Subject: 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. --- src/dotty/tools/dotc/typer/Inferencing.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') 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 -- cgit v1.2.3