aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/ConstraintHandling.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-02-05 13:14:24 +0100
committerMartin Odersky <odersky@gmail.com>2016-02-05 13:14:24 +0100
commit8358e979d328fcf430d6f895c39b3a3aae6e722e (patch)
treee74e03ebf973bde8c5385ef5b8c35b78fe267d65 /src/dotty/tools/dotc/core/ConstraintHandling.scala
parentf20b11ae7935664b88d0b1c81782e042356fc11b (diff)
downloaddotty-8358e979d328fcf430d6f895c39b3a3aae6e722e.tar.gz
dotty-8358e979d328fcf430d6f895c39b3a3aae6e722e.tar.bz2
dotty-8358e979d328fcf430d6f895c39b3a3aae6e722e.zip
Avoid `related` buffer in `addConstraint`.
Diffstat (limited to 'src/dotty/tools/dotc/core/ConstraintHandling.scala')
-rw-r--r--src/dotty/tools/dotc/core/ConstraintHandling.scala28
1 files changed, 17 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 36b93e123..2435fd9dc 100644
--- a/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -235,11 +235,12 @@ trait ConstraintHandling {
//checkPropagated(s"adding $description")(true) // DEBUG in case following fails
checkPropagated(s"added $description") {
addConstraintInvocations += 1
- val related = new mutable.ListBuffer[PolyParam]()
- /** Drop all constrained parameters that occur at the toplevel in bound
- * and add them to `related`, which means they will be handled by
- * `addLess` calls.
+ def addParamBound(bound: PolyParam) =
+ if (fromBelow) addLess(bound, param) else addLess(param, bound)
+
+ /** Drop all constrained parameters that occur at the toplevel in `bound` and
+ * handle them by `addLess` calls.
* The preconditions make sure that such parameters occur only
* in one of two ways:
*
@@ -269,27 +270,32 @@ trait ConstraintHandling {
* A test case that demonstrates the problem is i864.scala.
* Turn Config.checkConstraintsSeparated on to get an accurate diagnostic
* of the cycle when it is created.
+ *
+ * @return The pruned type if all `addLess` calls succeed, `NoType` otherwise.
*/
def prune(bound: Type): Type = bound match {
case bound: AndOrType =>
- bound.derivedAndOrType(prune(bound.tp1), prune(bound.tp2))
+ val p1 = prune(bound.tp1)
+ val p2 = prune(bound.tp2)
+ if (p1.exists && p2.exists) bound.derivedAndOrType(p1, p2)
+ else NoType
case bound: TypeVar if constraint contains bound.origin =>
prune(bound.underlying)
case bound: PolyParam if constraint contains bound =>
- related += bound
- if (fromBelow) defn.NothingType else defn.AnyType
+ if (!addParamBound(bound)) NoType
+ else if (fromBelow) defn.NothingType
+ else defn.AnyType
case _ =>
bound
}
- def addParamBound(bound: PolyParam) =
- if (fromBelow) addLess(bound, param) else addLess(param, bound)
+
try bound match {
case bound: PolyParam if constraint contains bound =>
addParamBound(bound)
case _ =>
val pbound = prune(bound)
- related.foreach(addParamBound)
- if (fromBelow) addLowerBound(param, pbound) else addUpperBound(param, pbound)
+ pbound.exists && (
+ if (fromBelow) addLowerBound(param, pbound) else addUpperBound(param, pbound))
}
finally addConstraintInvocations -= 1
}