@@ -302,14 +302,18 @@ trait ConstraintHandling {
302
302
false
303
303
else
304
304
val bound = legalBound(param, rawBound, isUpper)
305
+ lazy val recBound = bound.existsPart(_ eq param, StopAt .Static )
306
+
307
+ // If the narrowed bounds are equal and not recursive,
308
+ // we can remove `param` from the constraint.
309
+ def tryReplace (lo : Type , hi : Type ): Boolean =
310
+ val equalBounds = (if isUpper then lo else hi) eq bound
311
+ val canReplace = equalBounds && ! recBound
312
+ if canReplace then constraint = constraint.replace(param, bound)
313
+ canReplace
314
+
305
315
val oldBounds @ TypeBounds (lo, hi) = constraint.nonParamBounds(param)
306
- val equalBounds = (if isUpper then lo else hi) eq bound
307
- if equalBounds && ! bound.existsPart(_ eq param, StopAt .Static ) then
308
- // The narrowed bounds are equal and not recursive,
309
- // so we can remove `param` from the constraint.
310
- constraint = constraint.replace(param, bound)
311
- true
312
- else
316
+ tryReplace(lo, hi) || {
313
317
// Narrow one of the bounds of type parameter `param`
314
318
// If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
315
319
// that `param >: bound`.
@@ -328,8 +332,12 @@ trait ConstraintHandling {
328
332
|| {
329
333
constraint = c1
330
334
val TypeBounds (lo, hi) = constraint.entry(param): @ unchecked
331
- isSub(lo, hi)
335
+ isSub(lo, hi) && {
336
+ tryReplace(lo, hi) // isSub may have introduced new constraints
337
+ true
338
+ }
332
339
}
340
+ }
333
341
end addOneBound
334
342
335
343
protected def addBoundTransitively (param : TypeParamRef , rawBound : Type , isUpper : Boolean )(using Context ): Boolean =
0 commit comments