Skip to content

Commit 3a1c2c5

Browse files
Retry constraint.replace after constraint.updateEntry
Checking `isSub` on the resulting bounds can have introduced new constraints, which might allow us to replace the type parameter entirely.
1 parent 99c4c00 commit 3a1c2c5

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

+16-8
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,18 @@ trait ConstraintHandling {
302302
false
303303
else
304304
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+
305315
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) || {
313317
// Narrow one of the bounds of type parameter `param`
314318
// If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
315319
// that `param >: bound`.
@@ -328,8 +332,12 @@ trait ConstraintHandling {
328332
|| {
329333
constraint = c1
330334
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+
}
332339
}
340+
}
333341
end addOneBound
334342

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

0 commit comments

Comments
 (0)