diff options
author | Martin Odersky <odersky@gmail.com> | 2016-02-05 13:14:24 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-02-05 13:14:24 +0100 |
commit | 8358e979d328fcf430d6f895c39b3a3aae6e722e (patch) | |
tree | e74e03ebf973bde8c5385ef5b8c35b78fe267d65 /src/dotty/tools/dotc/core | |
parent | f20b11ae7935664b88d0b1c81782e042356fc11b (diff) | |
download | dotty-8358e979d328fcf430d6f895c39b3a3aae6e722e.tar.gz dotty-8358e979d328fcf430d6f895c39b3a3aae6e722e.tar.bz2 dotty-8358e979d328fcf430d6f895c39b3a3aae6e722e.zip |
Avoid `related` buffer in `addConstraint`.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/ConstraintHandling.scala | 28 |
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 } |