diff options
-rw-r--r-- | src/dotty/tools/dotc/core/Constraint.scala | 29 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 7 |
2 files changed, 19 insertions, 17 deletions
diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala index 010601450..9354e18f8 100644 --- a/src/dotty/tools/dotc/core/Constraint.scala +++ b/src/dotty/tools/dotc/core/Constraint.scala @@ -18,7 +18,7 @@ import config.Config * An instantiated type parameter is represented by having its instance type in * the corresponding array entry. */ -class Constraint(val myMap: SimpleMap[PolyType, Array[Type]]) extends AnyVal with Showable { +class Constraint(val myMap: SimpleMap[PolyType, Array[Type]]) extends Showable { /** Does the constraint's domain contain the type parameters of `pt`? */ def contains(pt: PolyType): Boolean = myMap(pt) != null @@ -106,7 +106,7 @@ class Constraint(val myMap: SimpleMap[PolyType, Array[Type]]) extends AnyVal wit } /** A new constraint which is derived from this constraint by mapping - * `op` over all entries of type `poly`. + * `op` over all entries of `poly`. * @pre `this contains poly`. */ def transformed(poly: PolyType, op: Type => Type)(implicit ctx: Context) : Constraint = @@ -245,27 +245,32 @@ class Constraint(val myMap: SimpleMap[PolyType, Array[Type]]) extends AnyVal wit /** Perform operation `op` on all typevars, or only on uninstantiated * typevars, depending on whether `uninstOnly` is set or not. */ - def foreachTypeVar(op: TypeVar => Unit, uninstOnly: Boolean = false): Unit = + def foreachTypeVar(op: TypeVar => Unit): Unit = myMap.foreachBinding { (poly, entries) => for (i <- 0 until paramCount(entries)) { - def qualifies(tv: TypeVar) = - if (uninstOnly) isBounds(entries(i)) else !tv.inst.exists typeVar(entries, i) match { - case tv: TypeVar if qualifies(tv) => op(tv) + case tv: TypeVar if !tv.inst.exists => op(tv) case _ => } } } - /** Perform operation `op` on all uninstantiated typevars. - */ - def foreachUninstVar(op: TypeVar => Unit): Unit = foreachTypeVar(op, uninstOnly = true) + private var myUninstVars: mutable.ArrayBuffer[TypeVar] = null /** The uninstantiated typevars of this constraint */ def uninstVars: collection.Seq[TypeVar] = { - val buf = new mutable.ArrayBuffer[TypeVar] - foreachUninstVar(buf += _) - buf + if (myUninstVars == null) { + myUninstVars = new mutable.ArrayBuffer[TypeVar] + myMap.foreachBinding { (poly, entries) => + for (i <- 0 until paramCount(entries)) { + typeVar(entries, i) match { + case tv: TypeVar if isBounds(entries(i)) => myUninstVars += tv + case _ => + } + } + } + } + myUninstVars } def constrainedTypesText(printer: Printer): Text = diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index cd30f8ff6..a8003f8c2 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -606,9 +606,7 @@ object Inferencing { val constraint = ctx.typerState.constraint constr.println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${constraint.uninstVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}") - constr.println(s"qualifying undet vars: ${constraint.uninstVars filter qualifies map (tvar => s"$tvar / ${tvar.show}")}") - constr.println(s"fulltype: $tp") // !!! DEBUG - constr.println(s"constraint: ${constraint.show}") + constr.println(s"qualifying undet vars: ${constraint.uninstVars filter qualifies map (tvar => s"$tvar / ${tvar.show}")}, constraint: ${constraint.show}") def qualifies(tvar: TypeVar) = tree contains tvar.owningTree val vs = tp.variances(tvar => (constraint contains tvar) && qualifies(tvar)) @@ -623,12 +621,11 @@ object Inferencing { if (changed) // instantiations might have uncovered new typevars to interpolate interpolateUndetVars(tree) else - constraint.foreachUninstVar { tvar => + for (tvar <- constraint.uninstVars) if (!(vs contains tvar) && qualifies(tvar)) { typr.println(s"instantiating non-occurring ${tvar.show} in ${tp.show}") tvar.instantiate(fromBelow = true) } - } } /** Instantiate undetermined type variables to that type `tp` is |