diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index 109929f0c6f5..656d1e1cf5a0 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -327,7 +327,7 @@ trait ConstraintHandling { (c1 eq constraint) || { constraint = c1 - val TypeBounds(lo, hi) = constraint.entry(param): @unchecked + val TypeBounds(lo, hi) = constraint.nonParamBounds(param) isSub(lo, hi) } end addOneBound diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala index 8256a3cdbab1..e3f93547c260 100644 --- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala +++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala @@ -104,6 +104,18 @@ object OrderingConstraint { def updateEntries(c: OrderingConstraint, poly: TypeLambda, entries: Array[Type])(using Context): OrderingConstraint = c.newConstraint(boundsMap = c.boundsMap.updated(poly, entries)) def initial = NoType + + override def update(prev: OrderingConstraint, current: OrderingConstraint, + poly: TypeLambda, idx: Int, entry: Type)(using Context): OrderingConstraint = + entry match + case TypeBounds(lo, hi) if lo eq hi => + val replaceParams = new TypeMap: + def apply(tp: Type): Type = tp match + case tp: TypeParamRef => current.typeVarOfParam(tp).orElse(tp) + case _ => mapOver(tp) + super.update(prev, current, poly, idx, replaceParams(hi)) + case _ => + super.update(prev, current, poly, idx, entry) } private val lowerLens: ConstraintLens[List[TypeParamRef]] = new ConstraintLens[List[TypeParamRef]] { @@ -477,26 +489,27 @@ class OrderingConstraint(private val boundsMap: ParamBounds, * @param isUpper If true, `bound` is an upper bound, else a lower bound. */ private def stripParams( + current: OrderingConstraint, tp: Type, todos: mutable.ListBuffer[(OrderingConstraint, TypeParamRef) => OrderingConstraint], isUpper: Boolean)(using Context): Type = tp match { - case param: TypeParamRef if contains(param) => + case param: TypeParamRef if current.contains(param) => todos += (if isUpper then order(_, _, param) else order(_, param, _)) NoType case tp: TypeBounds => - val lo1 = stripParams(tp.lo, todos, !isUpper).orElse(defn.NothingType) - val hi1 = stripParams(tp.hi, todos, isUpper).orElse(tp.topType) + val lo1 = stripParams(current, tp.lo, todos, !isUpper).orElse(defn.NothingType) + val hi1 = stripParams(current, tp.hi, todos, isUpper).orElse(tp.topType) tp.derivedTypeBounds(lo1, hi1) case tp: AndType if isUpper => - val tp1 = stripParams(tp.tp1, todos, isUpper) - val tp2 = stripParams(tp.tp2, todos, isUpper) + val tp1 = stripParams(current, tp.tp1, todos, isUpper) + val tp2 = stripParams(current, tp.tp2, todos, isUpper) if (tp1.exists) if (tp2.exists) tp.derivedAndType(tp1, tp2) else tp1 else tp2 case tp: OrType if !isUpper => - val tp1 = stripParams(tp.tp1, todos, isUpper) - val tp2 = stripParams(tp.tp2, todos, isUpper) + val tp1 = stripParams(current, tp.tp1, todos, isUpper) + val tp2 = stripParams(current, tp.tp2, todos, isUpper) if (tp1.exists) if (tp2.exists) tp.derivedOrType(tp1, tp2) else tp1 @@ -527,7 +540,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds, while (i < poly.paramNames.length) { val param = poly.paramRefs(i) val bounds = dropWildcards(nonParamBounds(param)) - val stripped = stripParams(bounds, todos, isUpper = true) + val stripped = stripParams(current, bounds, todos, isUpper = true) current = boundsLens.update(this, current, param, stripped) while todos.nonEmpty do current = todos.head(current, param)