Skip to content

Commit 8c0648a

Browse files
authored
Merge pull request #13031 from Linyxus/fix-param-unification
Fix ordering propagation during parameter unification in constraint solver
2 parents 9ecacb1 + d1fca8a commit 8c0648a

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ trait ConstraintHandling {
197197
private def unify(p1: TypeParamRef, p2: TypeParamRef)(using Context): Boolean = {
198198
constr.println(s"unifying $p1 $p2")
199199
assert(constraint.isLess(p1, p2))
200+
constraint = constraint.addLess(p2, p1)
200201
val down = constraint.exclusiveLower(p2, p1)
201202
val up = constraint.exclusiveUpper(p1, p2)
202203
constraint = constraint.unify(p1, p2)

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,27 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
355355
else {
356356
assert(contains(param1), i"$param1")
357357
assert(contains(param2), i"$param2")
358-
val newUpper = param2 :: exclusiveUpper(param2, param1)
359-
val newLower = param1 :: exclusiveLower(param1, param2)
358+
// Is `order` called during parameter unification?
359+
val unifying = isLess(param2, param1)
360+
val newUpper = {
361+
val up = exclusiveUpper(param2, param1)
362+
if unifying then
363+
// Since param2 <:< param1 already holds now, filter out param1 to avoid adding
364+
// duplicated orderings.
365+
param2 :: up.filterNot(_ eq param1)
366+
else
367+
param2 :: up
368+
}
369+
val newLower = {
370+
val lower = exclusiveLower(param1, param2)
371+
if unifying then
372+
// Do not add bounds for param1 since it will be unified to param2 soon.
373+
// And, similarly filter out param2 from lowerly-ordered parameters
374+
// to avoid duplicated orderings.
375+
lower.filterNot(_ eq param2)
376+
else
377+
param1 :: lower
378+
}
360379
val current1 = newLower.foldLeft(current)(upperLens.map(this, _, _, newUpper ::: _))
361380
val current2 = newUpper.foldLeft(current1)(lowerLens.map(this, _, _, newLower ::: _))
362381
current2
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
trait Expr[T]
2+
final class Lit[T] extends Expr[T]
3+
4+
def foo[X, T1 >: X, T2](m: Expr[T2]): T2 = m match {
5+
case _: Lit[T1] => ??? : X
6+
}

0 commit comments

Comments
 (0)