aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/core/Constraint.scala9
-rw-r--r--src/dotty/tools/dotc/core/ConstraintHandling.scala15
-rw-r--r--src/dotty/tools/dotc/core/OrderingConstraint.scala26
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 = {