@@ -235,11 +235,12 @@ trait ConstraintHandling {
235
235
// checkPropagated(s"adding $description")(true) // DEBUG in case following fails
236
236
checkPropagated(s " added $description" ) {
237
237
addConstraintInvocations += 1
238
- val related = new mutable.ListBuffer [PolyParam ]()
239
238
240
- /** Drop all constrained parameters that occur at the toplevel in bound
241
- * and add them to `related`, which means they will be handled by
242
- * `addLess` calls.
239
+ def addParamBound (bound : PolyParam ) =
240
+ if (fromBelow) addLess(bound, param) else addLess(param, bound)
241
+
242
+ /** Drop all constrained parameters that occur at the toplevel in `bound` and
243
+ * handle them by `addLess` calls.
243
244
* The preconditions make sure that such parameters occur only
244
245
* in one of two ways:
245
246
*
@@ -269,27 +270,32 @@ trait ConstraintHandling {
269
270
* A test case that demonstrates the problem is i864.scala.
270
271
* Turn Config.checkConstraintsSeparated on to get an accurate diagnostic
271
272
* of the cycle when it is created.
273
+ *
274
+ * @return The pruned type if all `addLess` calls succeed, `NoType` otherwise.
272
275
*/
273
276
def prune (bound : Type ): Type = bound match {
274
277
case bound : AndOrType =>
275
- bound.derivedAndOrType(prune(bound.tp1), prune(bound.tp2))
278
+ val p1 = prune(bound.tp1)
279
+ val p2 = prune(bound.tp2)
280
+ if (p1.exists && p2.exists) bound.derivedAndOrType(p1, p2)
281
+ else NoType
276
282
case bound : TypeVar if constraint contains bound.origin =>
277
283
prune(bound.underlying)
278
284
case bound : PolyParam if constraint contains bound =>
279
- related += bound
280
- if (fromBelow) defn.NothingType else defn.AnyType
285
+ if (! addParamBound(bound)) NoType
286
+ else if (fromBelow) defn.NothingType
287
+ else defn.AnyType
281
288
case _ =>
282
289
bound
283
290
}
284
- def addParamBound (bound : PolyParam ) =
285
- if (fromBelow) addLess(bound, param) else addLess(param, bound)
291
+
286
292
try bound match {
287
293
case bound : PolyParam if constraint contains bound =>
288
294
addParamBound(bound)
289
295
case _ =>
290
296
val pbound = prune(bound)
291
- related.foreach(addParamBound)
292
- if (fromBelow) addLowerBound(param, pbound) else addUpperBound(param, pbound)
297
+ pbound.exists && (
298
+ if (fromBelow) addLowerBound(param, pbound) else addUpperBound(param, pbound) )
293
299
}
294
300
finally addConstraintInvocations -= 1
295
301
}
0 commit comments