@@ -334,17 +334,6 @@ object Denotations {
334
334
else asSingleDenotation
335
335
}
336
336
337
- /** Handle merge conflict by throwing a `MergeError` exception */
338
- private def mergeConflict (tp1 : Type , tp2 : Type , that : Denotation )(implicit ctx : Context ): Type =
339
- throw new MergeError (this .symbol, that.symbol, tp1, tp2, NoPrefix )
340
-
341
- /** Merge parameter names of lambda types. If names in corresponding positions match, keep them,
342
- * otherwise generate new synthetic names.
343
- */
344
- private def mergeParamNames (tp1 : LambdaType , tp2 : LambdaType ): List [tp1.ThisName ] =
345
- (for ((name1, name2, idx) <- (tp1.paramNames, tp2.paramNames, tp1.paramNames.indices).zipped)
346
- yield if (name1 == name2) name1 else tp1.companion.syntheticParamName(idx)).toList
347
-
348
337
/** Form a denotation by conjoining with denotation `that`.
349
338
*
350
339
* NoDenotations are dropped. MultiDenotations are handled by merging
@@ -374,72 +363,6 @@ object Denotations {
374
363
* If SingleDenotations with different signatures are joined, return NoDenotation.
375
364
*/
376
365
def & (that : Denotation , pre : Type , safeIntersection : Boolean = false )(implicit ctx : Context ): Denotation = {
377
-
378
- /** Normally, `tp1 & tp2`. Special cases for matching methods and classes, with
379
- * the possibility of raising a merge error.
380
- */
381
- def infoMeet (tp1 : Type , tp2 : Type ): Type = {
382
- if (tp1 eq tp2) tp1
383
- else tp1 match {
384
- case tp1 : TypeBounds =>
385
- tp2 match {
386
- case tp2 : TypeBounds => if (safeIntersection) tp1 safe_& tp2 else tp1 & tp2
387
- case tp2 : ClassInfo if tp1 contains tp2 => tp2
388
- case _ => mergeConflict(tp1, tp2, that)
389
- }
390
- case tp1 : ClassInfo =>
391
- tp2 match {
392
- case tp2 : ClassInfo if tp1.cls eq tp2.cls => tp1.derivedClassInfo(tp1.prefix & tp2.prefix)
393
- case tp2 : TypeBounds if tp2 contains tp1 => tp1
394
- case _ => mergeConflict(tp1, tp2, that)
395
- }
396
-
397
- // Two remedial strategies:
398
- //
399
- // 1. Prefer method types over poly types. This is necessary to handle
400
- // overloaded definitions like the following
401
- //
402
- // def ++ [B >: A](xs: C[B]): D[B]
403
- // def ++ (xs: C[A]): D[A]
404
- //
405
- // (Code like this is found in the collection strawman)
406
- //
407
- // 2. In the case of two method types or two polytypes with matching
408
- // parameters and implicit status, merge corresponding parameter
409
- // and result types.
410
- case tp1 : MethodType =>
411
- tp2 match {
412
- case tp2 : PolyType =>
413
- tp1
414
- case tp2 : MethodType if ctx.typeComparer.matchingMethodParams(tp1, tp2) &&
415
- tp1.isImplicitMethod == tp2.isImplicitMethod =>
416
- tp1.derivedLambdaType(
417
- mergeParamNames(tp1, tp2),
418
- tp1.paramInfos,
419
- infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
420
- case _ =>
421
- mergeConflict(tp1, tp2, that)
422
- }
423
- case tp1 : PolyType =>
424
- tp2 match {
425
- case tp2 : MethodType =>
426
- tp2
427
- case tp2 : PolyType if ctx.typeComparer.matchingPolyParams(tp1, tp2) =>
428
- tp1.derivedLambdaType(
429
- mergeParamNames(tp1, tp2),
430
- tp1.paramInfos.zipWithConserve(tp2.paramInfos) { (p1, p2) =>
431
- infoMeet(p1, p2.subst(tp2, tp1)).bounds
432
- },
433
- infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
434
- case _ =>
435
- mergeConflict(tp1, tp2, that)
436
- }
437
-
438
- case _ =>
439
- tp1 & tp2
440
- }
441
- }
442
-
443
366
/** Try to merge denot1 and denot2 without adding a new signature. */
444
367
def mergeDenot (denot1 : Denotation , denot2 : SingleDenotation ): Denotation = denot1 match {
445
368
case denot1 @ MultiDenotation (denot11, denot12) =>
@@ -535,7 +458,7 @@ object Denotations {
535
458
if (preferSym(sym2, sym1)) sym2
536
459
else sym1
537
460
val jointInfo =
538
- try infoMeet(info1, info2)
461
+ try infoMeet(info1, info2, sym1, sym2, safeIntersection )
539
462
catch {
540
463
case ex : MergeError =>
541
464
// TODO: this picks one type over the other whereas it might be better
@@ -571,51 +494,6 @@ object Denotations {
571
494
*/
572
495
def | (that : Denotation , pre : Type )(implicit ctx : Context ): Denotation = {
573
496
574
- /** Normally, `tp1 | tp2`. Special cases for matching methods and classes, with
575
- * the possibility of raising a merge error.
576
- */
577
- def infoJoin (tp1 : Type , tp2 : Type ): Type = tp1 match {
578
- case tp1 : TypeBounds =>
579
- tp2 match {
580
- case tp2 : TypeBounds => tp1 | tp2
581
- case tp2 : ClassInfo if tp1 contains tp2 => tp1
582
- case _ => mergeConflict(tp1, tp2, that)
583
- }
584
- case tp1 : ClassInfo =>
585
- tp2 match {
586
- case tp2 : ClassInfo if tp1.cls eq tp2.cls => tp1.derivedClassInfo(tp1.prefix | tp2.prefix)
587
- case tp2 : TypeBounds if tp2 contains tp1 => tp2
588
- case _ => mergeConflict(tp1, tp2, that)
589
- }
590
- case tp1 : MethodType =>
591
- tp2 match {
592
- case tp2 : MethodType
593
- if ctx.typeComparer.matchingMethodParams(tp1, tp2) &&
594
- tp1.isImplicitMethod == tp2.isImplicitMethod =>
595
- tp1.derivedLambdaType(
596
- mergeParamNames(tp1, tp2),
597
- tp1.paramInfos,
598
- tp1.resultType | tp2.resultType.subst(tp2, tp1))
599
- case _ =>
600
- mergeConflict(tp1, tp2, that)
601
- }
602
- case tp1 : PolyType =>
603
- tp2 match {
604
- case tp2 : PolyType
605
- if ctx.typeComparer.matchingPolyParams(tp1, tp2) =>
606
- tp1.derivedLambdaType(
607
- mergeParamNames(tp1, tp2),
608
- tp1.paramInfos.zipWithConserve(tp2.paramInfos) { (p1, p2) =>
609
- (p1 | p2.subst(tp2, tp1)).bounds
610
- },
611
- tp1.resultType | tp2.resultType.subst(tp2, tp1))
612
- case _ =>
613
- mergeConflict(tp1, tp2, that)
614
- }
615
- case _ =>
616
- tp1 | tp2
617
- }
618
-
619
497
def unionDenot (denot1 : SingleDenotation , denot2 : SingleDenotation ): Denotation =
620
498
if (denot1.matches(denot2)) {
621
499
val sym1 = denot1.symbol
@@ -646,7 +524,7 @@ object Denotations {
646
524
lubSym(sym1.allOverriddenSymbols, NoSymbol )
647
525
}
648
526
new JointRefDenotation (
649
- jointSym, infoJoin(info1, info2), denot1.validFor & denot2.validFor)
527
+ jointSym, infoJoin(info1, info2, sym1, sym2 ), denot1.validFor & denot2.validFor)
650
528
}
651
529
}
652
530
else NoDenotation
@@ -678,6 +556,134 @@ object Denotations {
678
556
final def containsSym (sym : Symbol ): Boolean = hasUniqueSym && (symbol eq sym)
679
557
}
680
558
559
+ // ------ Info meets and joins ---------------------------------------------
560
+
561
+ /** Handle merge conflict by throwing a `MergeError` exception */
562
+ private def mergeConflict (sym1 : Symbol , sym2 : Symbol , tp1 : Type , tp2 : Type )(implicit ctx : Context ): Type =
563
+ throw new MergeError (sym1, sym2, tp1, tp2, NoPrefix )
564
+
565
+ /** Merge parameter names of lambda types. If names in corresponding positions match, keep them,
566
+ * otherwise generate new synthetic names.
567
+ */
568
+ private def mergeParamNames (tp1 : LambdaType , tp2 : LambdaType ): List [tp1.ThisName ] =
569
+ (for ((name1, name2, idx) <- (tp1.paramNames, tp2.paramNames, tp1.paramNames.indices).zipped)
570
+ yield if (name1 == name2) name1 else tp1.companion.syntheticParamName(idx)).toList
571
+
572
+ /** Normally, `tp1 & tp2`. Special cases for matching methods and classes, with
573
+ * the possibility of raising a merge error.
574
+ */
575
+ def infoMeet (tp1 : Type , tp2 : Type , sym1 : Symbol , sym2 : Symbol , safeIntersection : Boolean )(implicit ctx : Context ): Type = {
576
+ if (tp1 eq tp2) tp1
577
+ else tp1 match {
578
+ case tp1 : TypeBounds =>
579
+ tp2 match {
580
+ case tp2 : TypeBounds => if (safeIntersection) tp1 safe_& tp2 else tp1 & tp2
581
+ case tp2 : ClassInfo if tp1 contains tp2 => tp2
582
+ case _ => mergeConflict(sym1, sym2, tp1, tp2)
583
+ }
584
+ case tp1 : ClassInfo =>
585
+ tp2 match {
586
+ case tp2 : ClassInfo if tp1.cls eq tp2.cls => tp1.derivedClassInfo(tp1.prefix & tp2.prefix)
587
+ case tp2 : TypeBounds if tp2 contains tp1 => tp1
588
+ case _ => mergeConflict(sym1, sym2, tp1, tp2)
589
+ }
590
+
591
+ // Two remedial strategies:
592
+ //
593
+ // 1. Prefer method types over poly types. This is necessary to handle
594
+ // overloaded definitions like the following
595
+ //
596
+ // def ++ [B >: A](xs: C[B]): D[B]
597
+ // def ++ (xs: C[A]): D[A]
598
+ //
599
+ // (Code like this is found in the collection strawman)
600
+ //
601
+ // 2. In the case of two method types or two polytypes with matching
602
+ // parameters and implicit status, merge corresponding parameter
603
+ // and result types.
604
+ case tp1 : MethodType =>
605
+ tp2 match {
606
+ case tp2 : PolyType =>
607
+ tp1
608
+ case tp2 : MethodType if ctx.typeComparer.matchingMethodParams(tp1, tp2) &&
609
+ tp1.isImplicitMethod == tp2.isImplicitMethod =>
610
+ tp1.derivedLambdaType(
611
+ mergeParamNames(tp1, tp2),
612
+ tp1.paramInfos,
613
+ infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1), sym1, sym2, safeIntersection))
614
+ case _ =>
615
+ mergeConflict(sym1, sym2, tp1, tp2)
616
+ }
617
+ case tp1 : PolyType =>
618
+ tp2 match {
619
+ case tp2 : MethodType =>
620
+ tp2
621
+ case tp2 : PolyType if ctx.typeComparer.matchingPolyParams(tp1, tp2) =>
622
+ tp1.derivedLambdaType(
623
+ mergeParamNames(tp1, tp2),
624
+ tp1.paramInfos.zipWithConserve(tp2.paramInfos) { (p1, p2) =>
625
+ infoMeet(p1, p2.subst(tp2, tp1), sym1, sym2, safeIntersection).bounds
626
+ },
627
+ infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1), sym1, sym2, safeIntersection))
628
+ case _ =>
629
+ mergeConflict(sym1, sym2, tp1, tp2)
630
+ }
631
+
632
+ case _ =>
633
+ try tp1 & tp2
634
+ catch {
635
+ case ex : Throwable =>
636
+ println(i " error for meet: $tp1 &&& $tp2, ${tp1.getClass}, ${tp2.getClass}" )
637
+ throw ex
638
+ }
639
+ }
640
+ }
641
+
642
+ /** Normally, `tp1 | tp2`. Special cases for matching methods and classes, with
643
+ * the possibility of raising a merge error.
644
+ */
645
+ def infoJoin (tp1 : Type , tp2 : Type , sym1 : Symbol , sym2 : Symbol )(implicit ctx : Context ): Type = tp1 match {
646
+ case tp1 : TypeBounds =>
647
+ tp2 match {
648
+ case tp2 : TypeBounds => tp1 | tp2
649
+ case tp2 : ClassInfo if tp1 contains tp2 => tp1
650
+ case _ => mergeConflict(sym1, sym2, tp1, tp2)
651
+ }
652
+ case tp1 : ClassInfo =>
653
+ tp2 match {
654
+ case tp2 : ClassInfo if tp1.cls eq tp2.cls => tp1.derivedClassInfo(tp1.prefix | tp2.prefix)
655
+ case tp2 : TypeBounds if tp2 contains tp1 => tp2
656
+ case _ => mergeConflict(sym1, sym2, tp1, tp2)
657
+ }
658
+ case tp1 : MethodType =>
659
+ tp2 match {
660
+ case tp2 : MethodType
661
+ if ctx.typeComparer.matchingMethodParams(tp1, tp2) &&
662
+ tp1.isImplicitMethod == tp2.isImplicitMethod =>
663
+ tp1.derivedLambdaType(
664
+ mergeParamNames(tp1, tp2),
665
+ tp1.paramInfos,
666
+ tp1.resultType | tp2.resultType.subst(tp2, tp1))
667
+ case _ =>
668
+ mergeConflict(sym1, sym2, tp1, tp2)
669
+ }
670
+ case tp1 : PolyType =>
671
+ tp2 match {
672
+ case tp2 : PolyType
673
+ if ctx.typeComparer.matchingPolyParams(tp1, tp2) =>
674
+ tp1.derivedLambdaType(
675
+ mergeParamNames(tp1, tp2),
676
+ tp1.paramInfos.zipWithConserve(tp2.paramInfos) { (p1, p2) =>
677
+ (p1 | p2.subst(tp2, tp1)).bounds
678
+ },
679
+ tp1.resultType | tp2.resultType.subst(tp2, tp1))
680
+ case _ =>
681
+ mergeConflict(sym1, sym2, tp1, tp2)
682
+ }
683
+ case _ =>
684
+ tp1 | tp2
685
+ }
686
+
681
687
/** A non-overloaded denotation */
682
688
abstract class SingleDenotation (symbol : Symbol , initInfo : Type ) extends Denotation (symbol, initInfo) {
683
689
protected def newLikeThis (symbol : Symbol , info : Type ): SingleDenotation
0 commit comments