@@ -15,11 +15,13 @@ import annotation.tailrec
15
15
16
16
object OrderingConstraint {
17
17
18
+ type ArrayValuedMap [T ] = SimpleMap [GenericType , Array [T ]]
19
+
18
20
/** The type of `OrderingConstraint#boundsMap` */
19
- type ParamBounds = SimpleMap [ GenericType , Array [ Type ] ]
21
+ type ParamBounds = ArrayValuedMap [ Type ]
20
22
21
23
/** The type of `OrderingConstraint#lowerMap`, `OrderingConstraint#upperMap` */
22
- type ParamOrdering = SimpleMap [ GenericType , Array [ List [PolyParam ] ]]
24
+ type ParamOrdering = ArrayValuedMap [ List [PolyParam ]]
23
25
24
26
/** A new constraint with given maps */
25
27
private def newConstraint (boundsMap : ParamBounds , lowerMap : ParamOrdering , upperMap : ParamOrdering )(implicit ctx : Context ) : OrderingConstraint = {
@@ -495,6 +497,44 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
495
497
}
496
498
}
497
499
500
+ def & (other : Constraint )(implicit ctx : Context ) = {
501
+ def merge [T ](m1 : ArrayValuedMap [T ], m2 : ArrayValuedMap [T ], join : (T , T ) => T ): ArrayValuedMap [T ] = {
502
+ var merged = m1
503
+ def mergeArrays (xs1 : Array [T ], xs2 : Array [T ]) = {
504
+ val xs = xs1.clone
505
+ for (i <- xs.indices) xs(i) = join(xs1(i), xs2(i))
506
+ xs
507
+ }
508
+ m2.foreachBinding { (poly, xs2) =>
509
+ merged = merged.updated(poly,
510
+ if (m1.contains(poly)) mergeArrays(m1(poly), xs2) else xs2)
511
+ }
512
+ merged
513
+ }
514
+
515
+ def mergeParams (ps1 : List [PolyParam ], ps2 : List [PolyParam ]) =
516
+ (ps1 /: ps2)((ps1, p2) => if (ps1.contains(p2)) ps1 else p2 :: ps1)
517
+
518
+ def mergeEntries (e1 : Type , e2 : Type ): Type = e1 match {
519
+ case e1 : TypeBounds =>
520
+ e2 match {
521
+ case e2 : TypeBounds => e1 & e2
522
+ case _ if e1 contains e2 => e2
523
+ case _ => mergeError
524
+ }
525
+ case _ if e1 eq e2 => e1
526
+ case _ => mergeError
527
+ }
528
+
529
+ def mergeError = throw new AssertionError (i " cannot merge $this with $other" )
530
+
531
+ val that = other.asInstanceOf [OrderingConstraint ]
532
+ new OrderingConstraint (
533
+ merge(this .boundsMap, that.boundsMap, mergeEntries),
534
+ merge(this .lowerMap, that.lowerMap, mergeParams),
535
+ merge(this .upperMap, that.upperMap, mergeParams))
536
+ }
537
+
498
538
override def checkClosed ()(implicit ctx : Context ): Unit = {
499
539
def isFreePolyParam (tp : Type ) = tp match {
500
540
case PolyParam (binder : GenericType , _) => ! contains(binder)
0 commit comments