diff options
author | Martin Odersky <odersky@gmail.com> | 2014-01-02 17:59:26 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-01-02 17:59:26 +0100 |
commit | 1aaca404f83020a06a460d56841cd0a6b82b989b (patch) | |
tree | f8d3cecd19a7bae6ab36813182f21c169175d88e | |
parent | 37002e9fb650510e16cd038c5d7026bed50060f9 (diff) | |
download | dotty-1aaca404f83020a06a460d56841cd0a6b82b989b.tar.gz dotty-1aaca404f83020a06a460d56841cd0a6b82b989b.tar.bz2 dotty-1aaca404f83020a06a460d56841cd0a6b82b989b.zip |
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.
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 16 |
1 files 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) } |