aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/OrderingConstraint.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-08-26 10:26:22 +0200
committerMartin Odersky <odersky@gmail.com>2016-08-26 17:57:09 +0200
commiteef9be9817f5c0516e221aab1d14d748a12b386c (patch)
tree594a623f4eb0034e083621e58c98ff63dd5a1b40 /src/dotty/tools/dotc/core/OrderingConstraint.scala
parent959ea0cad3a2ffe441b5e406d26cddbd6cc431ee (diff)
downloaddotty-eef9be9817f5c0516e221aab1d14d748a12b386c.tar.gz
dotty-eef9be9817f5c0516e221aab1d14d748a12b386c.tar.bz2
dotty-eef9be9817f5c0516e221aab1d14d748a12b386c.zip
Implement constraint merging
Not used yet, but we might use it as an alternative to typedArg invalidation later.
Diffstat (limited to 'src/dotty/tools/dotc/core/OrderingConstraint.scala')
-rw-r--r--src/dotty/tools/dotc/core/OrderingConstraint.scala44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/OrderingConstraint.scala b/src/dotty/tools/dotc/core/OrderingConstraint.scala
index b0170b67c..e7e388be9 100644
--- a/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -15,11 +15,13 @@ import annotation.tailrec
object OrderingConstraint {
+ type ArrayValuedMap[T] = SimpleMap[GenericType, Array[T]]
+
/** The type of `OrderingConstraint#boundsMap` */
- type ParamBounds = SimpleMap[GenericType, Array[Type]]
+ type ParamBounds = ArrayValuedMap[Type]
/** The type of `OrderingConstraint#lowerMap`, `OrderingConstraint#upperMap` */
- type ParamOrdering = SimpleMap[GenericType, Array[List[PolyParam]]]
+ type ParamOrdering = ArrayValuedMap[List[PolyParam]]
/** A new constraint with given maps */
private def newConstraint(boundsMap: ParamBounds, lowerMap: ParamOrdering, upperMap: ParamOrdering)(implicit ctx: Context) : OrderingConstraint = {
@@ -495,6 +497,44 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
}
}
+ def & (other: Constraint)(implicit ctx: Context) = {
+ def merge[T](m1: ArrayValuedMap[T], m2: ArrayValuedMap[T], join: (T, T) => T): ArrayValuedMap[T] = {
+ var merged = m1
+ def mergeArrays(xs1: Array[T], xs2: Array[T]) = {
+ val xs = xs1.clone
+ for (i <- xs.indices) xs(i) = join(xs1(i), xs2(i))
+ xs
+ }
+ m2.foreachBinding { (poly, xs2) =>
+ merged = merged.updated(poly,
+ if (m1.contains(poly)) mergeArrays(m1(poly), xs2) else xs2)
+ }
+ merged
+ }
+
+ def mergeParams(ps1: List[PolyParam], ps2: List[PolyParam]) =
+ (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 _ if e1 eq e2 => e1
+ case _ => mergeError
+ }
+
+ def mergeError = throw new AssertionError(i"cannot merge $this with $other")
+
+ val that = other.asInstanceOf[OrderingConstraint]
+ new OrderingConstraint(
+ merge(this.boundsMap, that.boundsMap, mergeEntries),
+ merge(this.lowerMap, that.lowerMap, mergeParams),
+ merge(this.upperMap, that.upperMap, mergeParams))
+ }
+
override def checkClosed()(implicit ctx: Context): Unit = {
def isFreePolyParam(tp: Type) = tp match {
case PolyParam(binder: GenericType, _) => !contains(binder)