@@ -86,22 +86,24 @@ trait ConstraintHandling[AbstractContext] {
86
86
def fullBounds (param : TypeParamRef )(implicit actx : AbstractContext ): TypeBounds =
87
87
nonParamBounds(param).derivedTypeBounds(fullLowerBound(param), fullUpperBound(param))
88
88
89
- protected def addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean )(implicit actx : AbstractContext ): Boolean =
89
+ protected def addOneBound (param : TypeParamRef , rawBound : Type , isUpper : Boolean )(implicit actx : AbstractContext ): Boolean =
90
90
! constraint.contains(param) || {
91
- def occursIn (bound : Type ): Boolean = {
92
- val b = bound.dealias
93
- (b eq param) || {
94
- b match {
95
- case b : AndType => occursIn(b.tp1) || occursIn(b.tp2)
96
- case b : OrType => occursIn(b.tp1) || occursIn(b.tp2)
97
- case b : TypeVar => occursIn(b.origin)
98
- case b : TermRef => occursIn(b.underlying)
99
- case _ => false
100
- }
101
- }
102
- }
103
- if (Config .checkConstraintsSeparated)
104
- assert(! occursIn(bound), s " $param occurs in $bound" )
91
+ def avoidCycle (tp : Type ): Type = tp match
92
+ case tp : AndOrType =>
93
+ tp.derivedAndOrType(avoidCycle(tp.tp1), avoidCycle(tp.tp2))
94
+ case tp : TypeParamRef =>
95
+ if tp eq param then
96
+ // println(i"stripping $tp from $rawBound, upper = $isUpper in $constraint")
97
+ if isUpper then defn.AnyType else defn.NothingType
98
+ else constraint.entry(tp) match
99
+ case TypeBounds (lo, hi) => if lo eq hi then avoidCycle(lo) else tp
100
+ case inst => avoidCycle(inst)
101
+ case tp : TypeVar =>
102
+ val underlying1 = avoidCycle(tp.underlying)
103
+ if underlying1 eq tp.underlying then tp else underlying1
104
+ case _ =>
105
+ tp
106
+ val bound = avoidCycle(rawBound)
105
107
106
108
val oldBounds @ TypeBounds (lo, hi) = constraint.nonParamBounds(param)
107
109
val equalBounds = isUpper && (lo eq bound) || ! isUpper && (bound eq hi)
@@ -275,6 +277,9 @@ trait ConstraintHandling[AbstractContext] {
275
277
// from above | hi lo lo
276
278
//
277
279
if (variance == 0 || fromBelow == (variance < 0 )) bounds.lo else bounds.hi
280
+ case `param` =>
281
+ if variance == 0 || fromBelow == (variance < 0 ) then defn.AnyType
282
+ else defn.NothingType
278
283
case _ => tp
279
284
}
280
285
}
@@ -483,7 +488,7 @@ trait ConstraintHandling[AbstractContext] {
483
488
if bnd eq param then // (1)
484
489
if fromBelow then defn.NothingType else defn.AnyType
485
490
else constraint.entry(bnd) match
486
- case _ : TypeBounds => bnd
491
+ case TypeBounds (lo, hi) => if lo eq hi then prune(lo) else bnd
487
492
case inst => prune(inst) // (3)
488
493
case bnd : ExprType => // (4)
489
494
// ExprTypes are not value types, so type parameters should not
0 commit comments