aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Inferencing.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/typer/Inferencing.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala46
1 files changed, 25 insertions, 21 deletions
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index ebbd6cd41..8b3c19b71 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -204,15 +204,31 @@ object Inferencing {
* If the constraint contains already some of these parameters in its domain,
* make a copy of the polytype and add the copy's type parameters instead.
* Return either the original polytype, or the copy, if one was made.
+ * Also, if `owningTree` is non-empty, add a type variable for each parameter.
+ * @return The tracked polytype, and the list of created type variables.
*/
- def track(pt: PolyType): PolyType = {
+ def track(pt: PolyType, owningTree: untpd.Tree): (PolyType, List[TypeVar]) = {
val tracked =
if (state.constraint contains pt) pt.copy(pt.paramNames, pt.paramBounds, pt.resultType)
else pt
- state.constraint = state.constraint + tracked
- tracked
+ val tvars = if (owningTree.isEmpty) Nil else newTypeVars(tracked, owningTree)
+ state.constraint = state.constraint.add(tracked, tvars)
+ //if (!owningTree.isEmpty)
+ // state.constraint = state.constraint.transformed(pt, _.substParams(pt, tvars))
+ (tracked, tvars)
}
+ /** Create new type variables for the parameters of a poly type.
+ * @param pos The position of the new type variables (relevant for
+ * interpolateUndetVars
+ */
+ private def newTypeVars(pt: PolyType, owningTree: untpd.Tree): List[TypeVar] =
+ for (n <- (0 until pt.paramNames.length).toList)
+ yield new TypeVar(PolyParam(pt, n), ctx.typerState, owningTree)
+
+ /** Same as `track(pt, EmptyTree)`, but returns just the created polytype */
+ def track(pt: PolyType): PolyType = track(pt, EmptyTree)._1
+
/** Interpolate those undetermined type variables in the widened type of this tree
* which are introduced by type application contained in the tree.
* If such a variable appears covariantly in type `tp` or does not appear at all,
@@ -222,14 +238,14 @@ object Inferencing {
def interpolateUndetVars(tree: Tree): Unit = Stats.track("interpolateUndetVars") {
val tp = tree.tpe.widen
- println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${ctx.typerState.undetVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}")
- println(s"qualifying undet vars: ${ctx.typerState.undetVars filter qualifies map (_.show)}")
+ println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${ctx.typerState.uninstVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}")
+ println(s"qualifying undet vars: ${ctx.typerState.uninstVars filter qualifies map (_.show)}")
println(s"fulltype: $tp") // !!! DEBUG
println(s"constraint: ${ctx.typerState.constraint.show}")
def qualifies(tvar: TypeVar) = tree contains tvar.owningTree
val vs = tp.variances(tvar =>
- (ctx.typerState.undetVars contains tvar) && qualifies(tvar))
+ (ctx.typerState.constraint contains tvar) && qualifies(tvar))
println(s"variances = $vs")
var changed = false
for ((tvar, v) <- vs)
@@ -241,11 +257,12 @@ object Inferencing {
if (changed)
interpolateUndetVars(tree)
else
- for (tvar <- ctx.typerState.undetVars)
+ ctx.typerState.constraint.foreachUninstVar { tvar =>
if (!(vs contains tvar) && qualifies(tvar)) {
println(s"instantiating non-occurring $tvar in $tp")
tvar.instantiate(fromBelow = true)
}
+ }
}
/** Instantiate undetermined type variables to that type `tp` is
@@ -253,7 +270,7 @@ object Inferencing {
* typevar is not uniquely determined, return that typevar in a Some.
*/
def maximizeType(tp: Type): Option[TypeVar] = Stats.track("maximizeType") {
- val vs = tp.variances(tvar => ctx.typerState.undetVars contains tvar)
+ val vs = tp.variances(tvar => ctx.typerState.constraint contains tvar)
var result: Option[TypeVar] = None
for ((tvar, v) <- vs)
if (v == 1) tvar.instantiate(fromBelow = false)
@@ -266,19 +283,6 @@ object Inferencing {
result
}
- /** Create new type variables for the parameters of a poly type.
- * @param pos The position of the new type variables (relevant for
- * interpolateUndetVars
- */
- def newTypeVars(pt: PolyType, owningTree: untpd.Tree): List[TypeVar] = {
- val state = ctx.typerState
- val tvars =
- for (n <- (0 until pt.paramNames.length).toList)
- yield new TypeVar(PolyParam(pt, n), state, owningTree)
- state.constraint = state.constraint.transformed(pt, _.substParams(pt, tvars))
- tvars
- }
-
def isSubTypes(actuals: List[Type], formals: List[Type])(implicit ctx: Context): Boolean = formals match {
case formal :: formals1 =>
actuals match {