diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index ab6303acd821..e9ca12e3db9e 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -491,19 +491,23 @@ trait ConstraintHandling { checkPropagated(i"initialized $tl") { constraint = constraint.add(tl, tvars) tl.paramRefs.forall { param => + val lower = constraint.lower(param) + val upper = constraint.upper(param) constraint.entry(param) match { case bounds: TypeBounds => - val lower = constraint.lower(param) - val upper = constraint.upper(param) if lower.nonEmpty && !bounds.lo.isRef(defn.NothingClass) || upper.nonEmpty && !bounds.hi.isAny then constr.println(i"INIT*** $tl") lower.forall(addOneBound(_, bounds.hi, isUpper = true)) && upper.forall(addOneBound(_, bounds.lo, isUpper = false)) - case _ => + case x => // Happens if param was already solved while processing earlier params of the same TypeLambda. // See #4720. - true + + // Should propagate bounds even when param has been solved. + // See #11682. + lower.forall(addOneBound(_, x, isUpper = true)) && + upper.forall(addOneBound(_, x, isUpper = false)) } } } diff --git a/tests/pos/i11682.scala b/tests/pos/i11682.scala new file mode 100644 index 000000000000..47ce64e07858 --- /dev/null +++ b/tests/pos/i11682.scala @@ -0,0 +1,8 @@ +object Test { + final class Tag[T] + + def foo[Z >: Int <: Int, Y >: Z <: Z, X >: Y <: Y, T]: Tag[T] => T = { + case _ : Tag[X] => 0 + } +} +