From 1aaca404f83020a06a460d56841cd0a6b82b989b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 2 Jan 2014 17:59:26 +0100 Subject: Tweak to isFullyDefined The isFullyDefined accumulator will now maximize variables which are contravariant in the type, rather than minimizing them. Fits better in the general scheme and makes a pattern match in TreeInfo go through. --- src/dotty/tools/dotc/typer/Inferencing.scala | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 9608a854b..6623edc7d 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -10,6 +10,7 @@ import Constants._ import annotation.unchecked import util.Positions._ import util.{Stats, SimpleMap} +import util.common._ import Decorators._ import ErrorReporting.{errorType, InfoString} import collection.mutable @@ -224,14 +225,25 @@ object Inferencing { else throw new Error(i"internal error: type of $what $tp is not fully defined, pos = $pos") // !!! DEBUG private class IsFullyDefinedAccumulator(force: ForceDegree.Value)(implicit ctx: Context) extends TypeAccumulator[Boolean] { - def traverse(tp: Type): Boolean = apply(true, tp) + private var vs: SimpleMap[TypeVar, Integer] = null + private var rootTp: Type = null + def isContravariant(tvar: TypeVar) = { + (variance < 0) && { // otherwise no need to compute, it can't be contravariant + if (vs == null) vs = rootTp.variances(alwaysTrue) + vs(tvar) < 0 + } + } + def traverse(tp: Type): Boolean = { + rootTp = tp + apply(true, tp) + } def apply(x: Boolean, tp: Type) = !x || isOK(tp) && foldOver(x, tp) def isOK(tp: Type): Boolean = tp match { case _: WildcardType => false case tvar: TypeVar if !tvar.isInstantiated => force != ForceDegree.none && { - val inst = tvar.instantiate(fromBelow = true) + val inst = tvar.instantiate(fromBelow = !isContravariant(tvar)) println(i"forced instantiation of ${tvar.origin} = $inst") (force == ForceDegree.all || inst != defn.NothingType && inst != defn.NullType) && traverse(inst) } -- cgit v1.2.3