diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Constraint.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/ConstraintHandling.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/OrderingConstraint.scala | 26 |
3 files changed, 26 insertions, 24 deletions
diff --git a/src/dotty/tools/dotc/core/Constraint.scala b/src/dotty/tools/dotc/core/Constraint.scala index 38f714131..e480d1bfe 100644 --- a/src/dotty/tools/dotc/core/Constraint.scala +++ b/src/dotty/tools/dotc/core/Constraint.scala @@ -117,12 +117,11 @@ abstract class Constraint extends Showable { */ def narrowBound(param: PolyParam, bound: Type, isUpper: Boolean)(implicit ctx: Context): This - /** Is entry associated with `pt` removable? - * @param removedParam The index of a parameter which is still present in the - * entry array, but is going to be removed at the same step, - * or -1 if no such parameter exists. + /** Is entry associated with `pt` removable? This is the case if + * all type parameters of the entry are associated with type variables + * which have its `inst` fields set. */ - def isRemovable(pt: GenericType, removedParam: Int = -1): Boolean + def isRemovable(pt: GenericType): Boolean /** A new constraint with all entries coming from `pt` removed. */ def remove(pt: GenericType)(implicit ctx: Context): This diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala index ace441566..dfce9317b 100644 --- a/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -164,6 +164,7 @@ trait ConstraintHandling { } } } + assert(constraint.contains(param)) val bound = if (fromBelow) constraint.fullLowerBound(param) else constraint.fullUpperBound(param) val inst = avoidParam(bound) typr.println(s"approx ${param.show}, from below = $fromBelow, bound = ${bound.show}, inst = ${inst.show}") @@ -282,10 +283,16 @@ trait ConstraintHandling { else NoType case bound: TypeVar if constraint contains bound.origin => prune(bound.underlying) - case bound: PolyParam if constraint contains bound => - if (!addParamBound(bound)) NoType - else if (fromBelow) defn.NothingType - else defn.AnyType + case bound: PolyParam => + constraint.entry(bound) match { + case NoType => bound + case _: TypeBounds => + if (!addParamBound(bound)) NoType + else if (fromBelow) defn.NothingType + else defn.AnyType + case inst => + prune(inst) + } case _ => bound } diff --git a/src/dotty/tools/dotc/core/OrderingConstraint.scala b/src/dotty/tools/dotc/core/OrderingConstraint.scala index 1e284c341..b0170b67c 100644 --- a/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -11,6 +11,7 @@ import config.Config import config.Printers._ import collection.immutable.BitSet import reflect.ClassTag +import annotation.tailrec object OrderingConstraint { @@ -151,7 +152,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, def contains(param: PolyParam): Boolean = { val entries = boundsMap(param.binder) - entries != null && entries(param.paramNum).isInstanceOf[TypeBounds] + entries != null && isBounds(entries(param.paramNum)) } def contains(tvar: TypeVar): Boolean = { @@ -428,7 +429,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, } var current = - if (isRemovable(poly, idx)) remove(poly) else updateEntry(param, replacement) + if (isRemovable(poly)) remove(poly) else updateEntry(param, replacement) current.foreachParam {(p, i) => current = boundsLens.map(this, current, p, i, replaceParam(_, p, i)) current = lowerLens.map(this, current, p, i, removeParam) @@ -449,20 +450,15 @@ class OrderingConstraint(private val boundsMap: ParamBounds, newConstraint(boundsMap.remove(pt), removeFromOrdering(lowerMap), removeFromOrdering(upperMap)) } - def isRemovable(pt: GenericType, removedParam: Int = -1): Boolean = { + def isRemovable(pt: GenericType): Boolean = { val entries = boundsMap(pt) - var noneLeft = true - var i = paramCount(entries) - while (noneLeft && i > 0) { - i -= 1 - if (i != removedParam && isBounds(entries(i))) noneLeft = false - else typeVar(entries, i) match { - case tv: TypeVar => - if (!tv.inst.exists) noneLeft = false // need to keep line around to compute instType - case _ => + @tailrec def allRemovable(last: Int): Boolean = + if (last < 0) true + else typeVar(entries, last) match { + case tv: TypeVar => tv.inst.exists && allRemovable(last - 1) + case _ => false } - } - noneLeft + allRemovable(paramCount(entries) - 1) } // ---------- Exploration -------------------------------------------------------- @@ -473,7 +469,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, for { (poly, entries) <- boundsMap.toList n <- 0 until paramCount(entries) - if isBounds(entries(n)) + if entries(n).exists } yield PolyParam(poly, n) def forallParams(p: PolyParam => Boolean): Boolean = { |