aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Inferencing.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-01-02 17:59:26 +0100
committerMartin Odersky <odersky@gmail.com>2014-01-02 17:59:26 +0100
commit1aaca404f83020a06a460d56841cd0a6b82b989b (patch)
treef8d3cecd19a7bae6ab36813182f21c169175d88e /src/dotty/tools/dotc/typer/Inferencing.scala
parent37002e9fb650510e16cd038c5d7026bed50060f9 (diff)
downloaddotty-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.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Inferencing.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala16
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)
}