From d1024dd0fda953077da9958135c09916ef078e02 Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Mon, 9 Apr 2018 13:44:34 +0200
Subject: [PATCH 1/4] Refactor before fixing #4272
---
.../tools/dotc/core/OrderingConstraint.scala | 24 +++++++------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
index 73ed67a08208..3783c88746d3 100644
--- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -519,23 +519,15 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
def mergeParams(ps1: List[TypeParamRef], ps2: List[TypeParamRef]) =
(ps1 /: ps2)((ps1, p2) => if (ps1.contains(p2)) ps1 else p2 :: ps1)
- def mergeEntries(e1: Type, e2: Type): Type = e1 match {
- case e1: TypeBounds =>
- e2 match {
- case e2: TypeBounds => e1 & e2
- case _ if e1 contains e2 => e2
- case _ => mergeError
- }
- case tv1: TypeVar =>
- e2 match {
- case tv2: TypeVar if tv1.instanceOpt eq tv2.instanceOpt => e1
- case _ => mergeError
- }
+ def mergeEntries(e1: Type, e2: Type): Type =
+ (e1, e2) match {
+ case (e1: TypeBounds, e2: TypeBounds) => e1 & e2
+ case (e1: TypeBounds, _) if e1 contains e2 => e2
+ case (tv1: TypeVar, tv2: TypeVar) if tv1.instanceOpt eq tv2.instanceOpt => e1
case _ if e1 eq e2 => e1
- case _ => mergeError
- }
-
- def mergeError = throw new AssertionError(i"cannot merge $this with $other")
+ case _ =>
+ throw new AssertionError(i"cannot merge $this with $other")
+ }
val that = other.asInstanceOf[OrderingConstraint]
new OrderingConstraint(
From 7919795f2d45c599c572bf0fa05e64486d0af39c Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Mon, 9 Apr 2018 13:48:05 +0200
Subject: [PATCH 2/4] Optimize (possibly)
---
compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
index 3783c88746d3..e324bd349d33 100644
--- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -521,10 +521,10 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
def mergeEntries(e1: Type, e2: Type): Type =
(e1, e2) match {
+ case _ if e1 eq e2 => e1
case (e1: TypeBounds, e2: TypeBounds) => e1 & e2
case (e1: TypeBounds, _) if e1 contains e2 => e2
case (tv1: TypeVar, tv2: TypeVar) if tv1.instanceOpt eq tv2.instanceOpt => e1
- case _ if e1 eq e2 => e1
case _ =>
throw new AssertionError(i"cannot merge $this with $other")
}
From c9b97809116cbf495cd64a6ad15b0212596c374d Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Mon, 9 Apr 2018 13:49:22 +0200
Subject: [PATCH 3/4] Improve error message
---
compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
index e324bd349d33..7257023fad24 100644
--- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -526,7 +526,7 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
case (e1: TypeBounds, _) if e1 contains e2 => e2
case (tv1: TypeVar, tv2: TypeVar) if tv1.instanceOpt eq tv2.instanceOpt => e1
case _ =>
- throw new AssertionError(i"cannot merge $this with $other")
+ throw new AssertionError(i"cannot merge $this with $other, mergeEntries($e1, $e2) failed")
}
val that = other.asInstanceOf[OrderingConstraint]
From a3aee68d7e085a165f425e0cd2b8313fe959183a Mon Sep 17 00:00:00 2001
From: "Paolo G. Giarrusso"
Date: Mon, 9 Apr 2018 13:51:37 +0200
Subject: [PATCH 4/4] 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.
---
compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala | 2 ++
tests/neg/i4272.scala | 5 +++++
2 files changed, 7 insertions(+)
create mode 100644 tests/neg/i4272.scala
diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
index 7257023fad24..47700da1090b 100644
--- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -519,11 +519,13 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
def mergeParams(ps1: List[TypeParamRef], ps2: List[TypeParamRef]) =
(ps1 /: ps2)((ps1, p2) => if (ps1.contains(p2)) ps1 else p2 :: ps1)
+ // Must be symmetric
def mergeEntries(e1: Type, e2: Type): Type =
(e1, e2) match {
case _ if e1 eq e2 => e1
case (e1: TypeBounds, e2: TypeBounds) => e1 & e2
case (e1: TypeBounds, _) if e1 contains e2 => e2
+ case (_, e2: TypeBounds) if e2 contains e1 => e1
case (tv1: TypeVar, tv2: TypeVar) if tv1.instanceOpt eq tv2.instanceOpt => e1
case _ =>
throw new AssertionError(i"cannot merge $this with $other, mergeEntries($e1, $e2) failed")
diff --git a/tests/neg/i4272.scala b/tests/neg/i4272.scala
new file mode 100644
index 000000000000..933ba1b27ca0
--- /dev/null
+++ b/tests/neg/i4272.scala
@@ -0,0 +1,5 @@
+object Main {
+ def f(m: Map[String, Boolean]) = {}
+ println(f(Map('a' -> true))) // error
+ println(this.f(Map('a' -> true))) // error
+}