@@ -112,7 +112,7 @@ trait ConstraintHandling {
112
112
*/
113
113
private var myTrustBounds = true
114
114
115
- inline def withUntrustedBounds (op : => Type ): Type =
115
+ transparent inline def withUntrustedBounds (op : => Type ): Type =
116
116
val saved = myTrustBounds
117
117
myTrustBounds = false
118
118
try op finally myTrustBounds = saved
@@ -293,34 +293,44 @@ trait ConstraintHandling {
293
293
// so we shouldn't allow them as constraints either.
294
294
false
295
295
else
296
- val bound = legalBound(param, rawBound, isUpper)
297
- val oldBounds @ TypeBounds (lo, hi) = constraint.nonParamBounds(param)
298
- val equalBounds = (if isUpper then lo else hi) eq bound
299
- if equalBounds && ! bound.existsPart(_ eq param, StopAt .Static ) then
300
- // The narrowed bounds are equal and not recursive,
301
- // so we can remove `param` from the constraint.
302
- constraint = constraint.replace(param, bound)
303
- true
304
- else
305
- // Narrow one of the bounds of type parameter `param`
306
- // If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
307
- // that `param >: bound`.
308
- val narrowedBounds =
309
- val saved = homogenizeArgs
310
- homogenizeArgs = Config .alignArgsInAnd
311
- try
312
- withUntrustedBounds(
313
- if isUpper then oldBounds.derivedTypeBounds(lo, hi & bound)
314
- else oldBounds.derivedTypeBounds(lo | bound, hi))
315
- finally
316
- homogenizeArgs = saved
296
+
297
+ // Narrow one of the bounds of type parameter `param`
298
+ // If `isUpper` is true, ensure that `param <: `bound`,
299
+ // otherwise ensure that `param >: bound`.
300
+ val narrowedBounds : TypeBounds =
301
+ val bound = legalBound(param, rawBound, isUpper)
302
+ val oldBounds @ TypeBounds (lo, hi) = constraint.nonParamBounds(param)
303
+
304
+ val saved = homogenizeArgs
305
+ homogenizeArgs = Config .alignArgsInAnd
306
+ try
307
+ withUntrustedBounds(
308
+ if isUpper then oldBounds.derivedTypeBounds(lo, hi & bound)
309
+ else oldBounds.derivedTypeBounds(lo | bound, hi))
310
+ finally
311
+ homogenizeArgs = saved
312
+ end narrowedBounds
313
+
314
+ // If the narrowed bounds are equal and not recursive,
315
+ // we can remove `param` from the constraint.
316
+ def tryReplace (newBounds : TypeBounds ): Boolean =
317
+ val TypeBounds (lo, hi) = newBounds
318
+ val canReplace = (lo eq hi) && ! newBounds.existsPart(_ eq param, StopAt .Static )
319
+ if canReplace then constraint = constraint.replace(param, lo)
320
+ canReplace
321
+
322
+ tryReplace(narrowedBounds) || locally :
317
323
// println(i"narrow bounds for $param from $oldBounds to $narrowedBounds")
318
324
val c1 = constraint.updateEntry(param, narrowedBounds)
319
325
(c1 eq constraint)
320
326
|| {
321
327
constraint = c1
322
328
val TypeBounds (lo, hi) = constraint.entry(param): @ unchecked
323
- isSub(lo, hi)
329
+ val isSat = isSub(lo, hi)
330
+ if isSat then
331
+ // isSub may have narrowed the bounds further
332
+ tryReplace(constraint.nonParamBounds(param))
333
+ isSat
324
334
}
325
335
end addOneBound
326
336
0 commit comments