Skip to content

Commit 8daccbd

Browse files
Retry constraint.replace after constraint.updateEntry
Checking `isSub` on the resulting bounds may have introduced new constraints, which might allow us to replace the type parameter entirely.
1 parent 63810dc commit 8daccbd

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

+18-8
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,19 @@ trait ConstraintHandling {
302302
false
303303
else
304304
val bound = legalBound(param, rawBound, isUpper)
305+
306+
// If the narrowed bounds are equal and not recursive,
307+
// we can remove `param` from the constraint.
308+
def replaceIfEqualBounds: Boolean =
309+
val TypeBounds(lo, hi) = constraint.nonParamBounds(param)
310+
val equalBounds = (if isUpper then lo else hi) eq bound
311+
if equalBounds && !bound.existsPart(_ eq param, StopAt.Static) then
312+
constraint = constraint.replace(param, bound)
313+
true
314+
else false
315+
305316
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
317+
replaceIfEqualBounds || {
313318
// Narrow one of the bounds of type parameter `param`
314319
// If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
315320
// that `param >: bound`.
@@ -328,8 +333,13 @@ trait ConstraintHandling {
328333
|| {
329334
constraint = c1
330335
val TypeBounds(lo, hi) = constraint.entry(param): @unchecked
331-
isSub(lo, hi)
336+
isSub(lo, hi) && {
337+
// isSub may have introduced new constraints
338+
replaceIfEqualBounds
339+
true
340+
}
332341
}
342+
}
333343
end addOneBound
334344

335345
protected def addBoundTransitively(param: TypeParamRef, rawBound: Type, isUpper: Boolean)(using Context): Boolean =

0 commit comments

Comments
 (0)