Skip to content

Commit 23464fd

Browse files
committed
Fix #4272: make OrderingConstraint.&.mergeEntries symmetric
Debugging revealed that in the failing testcase `e2: TypeBounds` while `e1: TypeRef`, and it's not clear why it should be otherwise. Other fixes are possible, this one is easy to maintain but will repeat a few checks.
1 parent b1d9162 commit 23464fd

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
519519
def mergeParams(ps1: List[TypeParamRef], ps2: List[TypeParamRef]) =
520520
(ps1 /: ps2)((ps1, p2) => if (ps1.contains(p2)) ps1 else p2 :: ps1)
521521

522-
def mergeEntries(e1: Type, e2: Type): Type = e1 match {
522+
@tailrec
523+
def mergeEntries(e1: Type, e2: Type, retry: Boolean = true): Type = e1 match {
523524
case e1: TypeBounds =>
524525
e2 match {
525526
case e2: TypeBounds => e1 & e2
@@ -532,14 +533,18 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
532533
case _ => mergeError
533534
}
534535
case _ if e1 eq e2 => e1
535-
case _ => mergeError
536+
case _ if retry =>
537+
// mergeEntries must be commutative
538+
mergeEntries(e2, e1, false)
539+
case _ =>
540+
mergeError
536541
}
537542

538543
def mergeError = throw new AssertionError(i"cannot merge $this with $other")
539544

540545
val that = other.asInstanceOf[OrderingConstraint]
541546
new OrderingConstraint(
542-
merge(this.boundsMap, that.boundsMap, mergeEntries),
547+
merge(this.boundsMap, that.boundsMap, mergeEntries(_, _)),
543548
merge(this.lowerMap, that.lowerMap, mergeParams),
544549
merge(this.upperMap, that.upperMap, mergeParams))
545550
}

tests/neg/i4272.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
case class C(m: Map[String, Boolean])
2+
object Main {
3+
println(C(Map('a' -> true))) // error
4+
}

0 commit comments

Comments
 (0)