src/share/classes/com/sun/tools/javac/comp/Infer.java

changeset 1905
f65a807714ba
parent 1903
155809b1b969
child 1919
3155e77d2676
equal deleted inserted replaced
1904:b577222ef7b3 1905:f65a807714ba
459 if (!mlistener.changed || !allowGraphInference) break; 459 if (!mlistener.changed || !allowGraphInference) break;
460 } 460 }
461 } 461 }
462 finally { 462 finally {
463 mlistener.detach(); 463 mlistener.detach();
464 if (mlistener.rounds == MAX_INCORPORATION_STEPS) { 464 if (incorporationCache.size() == MAX_INCORPORATION_STEPS) {
465 inferenceContext.rollback(saved_undet); 465 inferenceContext.rollback(saved_undet);
466 } 466 }
467 incorporationCache.clear();
467 } 468 }
468 } 469 }
469 //where 470 //where
470 /** 471 /**
471 * This listener keeps track of changes on a group of inference variable 472 * This listener keeps track of changes on a group of inference variable
473 * method) to make sure that the underlying inference variable is 474 * method) to make sure that the underlying inference variable is
474 * left in a clean state. 475 * left in a clean state.
475 */ 476 */
476 class MultiUndetVarListener implements UndetVar.UndetVarListener { 477 class MultiUndetVarListener implements UndetVar.UndetVarListener {
477 478
478 int rounds;
479 boolean changed; 479 boolean changed;
480 List<Type> undetvars; 480 List<Type> undetvars;
481 481
482 public MultiUndetVarListener(List<Type> undetvars) { 482 public MultiUndetVarListener(List<Type> undetvars) {
483 this.undetvars = undetvars; 483 this.undetvars = undetvars;
487 } 487 }
488 } 488 }
489 489
490 public void varChanged(UndetVar uv, Set<InferenceBound> ibs) { 490 public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
491 //avoid non-termination 491 //avoid non-termination
492 if (rounds < MAX_INCORPORATION_STEPS) { 492 if (incorporationCache.size() < MAX_INCORPORATION_STEPS) {
493 changed = true; 493 changed = true;
494 } 494 }
495 } 495 }
496 496
497 void reset() { 497 void reset() {
498 rounds++;
499 changed = false; 498 changed = false;
500 } 499 }
501 500
502 void detach() { 501 void detach() {
503 for (Type t : undetvars) { 502 for (Type t : undetvars) {
526 uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types); 525 uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types);
527 infer.checkCompatibleUpperBounds(uv, inferenceContext); 526 infer.checkCompatibleUpperBounds(uv, inferenceContext);
528 if (uv.inst != null) { 527 if (uv.inst != null) {
529 Type inst = uv.inst; 528 Type inst = uv.inst;
530 for (Type u : uv.getBounds(InferenceBound.UPPER)) { 529 for (Type u : uv.getBounds(InferenceBound.UPPER)) {
531 if (!infer.types.isSubtypeUnchecked(inst, inferenceContext.asFree(u), warn)) { 530 if (!isSubtype(inst, inferenceContext.asFree(u), warn, infer)) {
532 infer.reportBoundError(uv, BoundErrorKind.UPPER); 531 infer.reportBoundError(uv, BoundErrorKind.UPPER);
533 } 532 }
534 } 533 }
535 for (Type l : uv.getBounds(InferenceBound.LOWER)) { 534 for (Type l : uv.getBounds(InferenceBound.LOWER)) {
536 if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), inst, warn)) { 535 if (!isSubtype(inferenceContext.asFree(l), inst, warn, infer)) {
537 infer.reportBoundError(uv, BoundErrorKind.LOWER); 536 infer.reportBoundError(uv, BoundErrorKind.LOWER);
538 } 537 }
539 } 538 }
540 for (Type e : uv.getBounds(InferenceBound.EQ)) { 539 for (Type e : uv.getBounds(InferenceBound.EQ)) {
541 if (!infer.types.isSameType(inst, inferenceContext.asFree(e))) { 540 if (!isSameType(inst, inferenceContext.asFree(e), infer)) {
542 infer.reportBoundError(uv, BoundErrorKind.EQ); 541 infer.reportBoundError(uv, BoundErrorKind.EQ);
543 } 542 }
544 } 543 }
545 } 544 }
546 } 545 }
559 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 558 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
560 Infer infer = inferenceContext.infer(); 559 Infer infer = inferenceContext.infer();
561 Type eq = null; 560 Type eq = null;
562 for (Type e : uv.getBounds(InferenceBound.EQ)) { 561 for (Type e : uv.getBounds(InferenceBound.EQ)) {
563 Assert.check(!inferenceContext.free(e)); 562 Assert.check(!inferenceContext.free(e));
564 if (eq != null && !infer.types.isSameType(e, eq)) { 563 if (eq != null && !isSameType(e, eq, infer)) {
565 infer.reportBoundError(uv, BoundErrorKind.EQ); 564 infer.reportBoundError(uv, BoundErrorKind.EQ);
566 } 565 }
567 eq = e; 566 eq = e;
568 for (Type l : uv.getBounds(InferenceBound.LOWER)) { 567 for (Type l : uv.getBounds(InferenceBound.LOWER)) {
569 Assert.check(!inferenceContext.free(l)); 568 Assert.check(!inferenceContext.free(l));
570 if (!infer.types.isSubtypeUnchecked(l, e, warn)) { 569 if (!isSubtype(l, e, warn, infer)) {
571 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER); 570 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
572 } 571 }
573 } 572 }
574 for (Type u : uv.getBounds(InferenceBound.UPPER)) { 573 for (Type u : uv.getBounds(InferenceBound.UPPER)) {
575 if (inferenceContext.free(u)) continue; 574 if (inferenceContext.free(u)) continue;
576 if (!infer.types.isSubtypeUnchecked(e, u, warn)) { 575 if (!isSubtype(e, u, warn, infer)) {
577 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER); 576 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
578 } 577 }
579 } 578 }
580 } 579 }
581 } 580 }
587 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 586 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
588 Infer infer = inferenceContext.infer(); 587 Infer infer = inferenceContext.infer();
589 for (Type e : uv.getBounds(InferenceBound.EQ)) { 588 for (Type e : uv.getBounds(InferenceBound.EQ)) {
590 if (e.containsAny(inferenceContext.inferenceVars())) continue; 589 if (e.containsAny(inferenceContext.inferenceVars())) continue;
591 for (Type u : uv.getBounds(InferenceBound.UPPER)) { 590 for (Type u : uv.getBounds(InferenceBound.UPPER)) {
592 if (!infer.types.isSubtypeUnchecked(e, inferenceContext.asFree(u), warn)) { 591 if (!isSubtype(e, inferenceContext.asFree(u), warn, infer)) {
593 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER); 592 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
594 } 593 }
595 } 594 }
596 for (Type l : uv.getBounds(InferenceBound.LOWER)) { 595 for (Type l : uv.getBounds(InferenceBound.LOWER)) {
597 if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), e, warn)) { 596 if (!isSubtype(inferenceContext.asFree(l), e, warn, infer)) {
598 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER); 597 infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
599 } 598 }
600 } 599 }
601 } 600 }
602 } 601 }
608 CROSS_UPPER_LOWER() { 607 CROSS_UPPER_LOWER() {
609 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 608 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
610 Infer infer = inferenceContext.infer(); 609 Infer infer = inferenceContext.infer();
611 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { 610 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
612 for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { 611 for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
613 infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); 612 isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn , infer);
614 } 613 }
615 } 614 }
616 } 615 }
617 }, 616 },
618 /** 617 /**
622 CROSS_UPPER_EQ() { 621 CROSS_UPPER_EQ() {
623 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 622 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
624 Infer infer = inferenceContext.infer(); 623 Infer infer = inferenceContext.infer();
625 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) { 624 for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
626 for (Type b2 : uv.getBounds(InferenceBound.EQ)) { 625 for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
627 infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); 626 isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer);
628 } 627 }
629 } 628 }
630 } 629 }
631 }, 630 },
632 /** 631 /**
636 CROSS_EQ_LOWER() { 635 CROSS_EQ_LOWER() {
637 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 636 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
638 Infer infer = inferenceContext.infer(); 637 Infer infer = inferenceContext.infer();
639 for (Type b1 : uv.getBounds(InferenceBound.EQ)) { 638 for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
640 for (Type b2 : uv.getBounds(InferenceBound.LOWER)) { 639 for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
641 infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); 640 isSubtype(inferenceContext.asFree(b2), inferenceContext.asFree(b1), warn, infer);
642 } 641 }
643 } 642 }
644 } 643 }
645 }, 644 },
646 /** 645 /**
651 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { 650 public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
652 Infer infer = inferenceContext.infer(); 651 Infer infer = inferenceContext.infer();
653 for (Type b1 : uv.getBounds(InferenceBound.EQ)) { 652 for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
654 for (Type b2 : uv.getBounds(InferenceBound.EQ)) { 653 for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
655 if (b1 != b2) { 654 if (b1 != b2) {
656 infer.types.isSameType(inferenceContext.asFree(b2), inferenceContext.asFree(b1)); 655 isSameType(inferenceContext.asFree(b2), inferenceContext.asFree(b1), infer);
657 } 656 }
658 } 657 }
659 } 658 }
660 } 659 }
661 }, 660 },
670 if (inferenceContext.inferenceVars().contains(b)) { 669 if (inferenceContext.inferenceVars().contains(b)) {
671 UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); 670 UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
672 if (uv2.isCaptured()) continue; 671 if (uv2.isCaptured()) continue;
673 //alpha <: beta 672 //alpha <: beta
674 //0. set beta :> alpha 673 //0. set beta :> alpha
675 uv2.addBound(InferenceBound.LOWER, uv, infer.types); 674 addBound(InferenceBound.LOWER, uv2, inferenceContext.asInstType(uv.qtype), infer);
676 //1. copy alpha's lower to beta's 675 //1. copy alpha's lower to beta's
677 for (Type l : uv.getBounds(InferenceBound.LOWER)) { 676 for (Type l : uv.getBounds(InferenceBound.LOWER)) {
678 uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types); 677 addBound(InferenceBound.LOWER, uv2, inferenceContext.asInstType(l), infer);
679 } 678 }
680 //2. copy beta's upper to alpha's 679 //2. copy beta's upper to alpha's
681 for (Type u : uv2.getBounds(InferenceBound.UPPER)) { 680 for (Type u : uv2.getBounds(InferenceBound.UPPER)) {
682 uv.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types); 681 addBound(InferenceBound.UPPER, uv, inferenceContext.asInstType(u), infer);
683 } 682 }
684 } 683 }
685 } 684 }
686 } 685 }
687 }, 686 },
696 if (inferenceContext.inferenceVars().contains(b)) { 695 if (inferenceContext.inferenceVars().contains(b)) {
697 UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); 696 UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
698 if (uv2.isCaptured()) continue; 697 if (uv2.isCaptured()) continue;
699 //alpha :> beta 698 //alpha :> beta
700 //0. set beta <: alpha 699 //0. set beta <: alpha
701 uv2.addBound(InferenceBound.UPPER, uv, infer.types); 700 addBound(InferenceBound.UPPER, uv2, inferenceContext.asInstType(uv.qtype), infer);
702 //1. copy alpha's upper to beta's 701 //1. copy alpha's upper to beta's
703 for (Type u : uv.getBounds(InferenceBound.UPPER)) { 702 for (Type u : uv.getBounds(InferenceBound.UPPER)) {
704 uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types); 703 addBound(InferenceBound.UPPER, uv2, inferenceContext.asInstType(u), infer);
705 } 704 }
706 //2. copy beta's lower to alpha's 705 //2. copy beta's lower to alpha's
707 for (Type l : uv2.getBounds(InferenceBound.LOWER)) { 706 for (Type l : uv2.getBounds(InferenceBound.LOWER)) {
708 uv.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types); 707 addBound(InferenceBound.LOWER, uv, inferenceContext.asInstType(l), infer);
709 } 708 }
710 } 709 }
711 } 710 }
712 } 711 }
713 }, 712 },
722 if (inferenceContext.inferenceVars().contains(b)) { 721 if (inferenceContext.inferenceVars().contains(b)) {
723 UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); 722 UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
724 if (uv2.isCaptured()) continue; 723 if (uv2.isCaptured()) continue;
725 //alpha == beta 724 //alpha == beta
726 //0. set beta == alpha 725 //0. set beta == alpha
727 uv2.addBound(InferenceBound.EQ, uv, infer.types); 726 addBound(InferenceBound.EQ, uv2, inferenceContext.asInstType(uv.qtype), infer);
728 //1. copy all alpha's bounds to beta's 727 //1. copy all alpha's bounds to beta's
729 for (InferenceBound ib : InferenceBound.values()) { 728 for (InferenceBound ib : InferenceBound.values()) {
730 for (Type b2 : uv.getBounds(ib)) { 729 for (Type b2 : uv.getBounds(ib)) {
731 if (b2 != uv2) { 730 if (b2 != uv2) {
732 uv2.addBound(ib, inferenceContext.asInstType(b2), infer.types); 731 addBound(ib, uv2, inferenceContext.asInstType(b2), infer);
733 } 732 }
734 } 733 }
735 } 734 }
736 //2. copy all beta's bounds to alpha's 735 //2. copy all beta's bounds to alpha's
737 for (InferenceBound ib : InferenceBound.values()) { 736 for (InferenceBound ib : InferenceBound.values()) {
738 for (Type b2 : uv2.getBounds(ib)) { 737 for (Type b2 : uv2.getBounds(ib)) {
739 if (b2 != uv) { 738 if (b2 != uv) {
740 uv.addBound(ib, inferenceContext.asInstType(b2), infer.types); 739 addBound(ib, uv, inferenceContext.asInstType(b2), infer);
741 } 740 }
742 } 741 }
743 } 742 }
744 } 743 }
745 } 744 }
748 747
749 abstract void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn); 748 abstract void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn);
750 749
751 boolean accepts(UndetVar uv, InferenceContext inferenceContext) { 750 boolean accepts(UndetVar uv, InferenceContext inferenceContext) {
752 return !uv.isCaptured(); 751 return !uv.isCaptured();
752 }
753
754 boolean isSubtype(Type s, Type t, Warner warn, Infer infer) {
755 return doIncorporationOp(IncorporationBinaryOpKind.IS_SUBTYPE, s, t, warn, infer);
756 }
757
758 boolean isSameType(Type s, Type t, Infer infer) {
759 return doIncorporationOp(IncorporationBinaryOpKind.IS_SAME_TYPE, s, t, null, infer);
760 }
761
762 void addBound(InferenceBound ib, UndetVar uv, Type b, Infer infer) {
763 doIncorporationOp(opFor(ib), uv, b, null, infer);
764 }
765
766 IncorporationBinaryOpKind opFor(InferenceBound boundKind) {
767 switch (boundKind) {
768 case EQ:
769 return IncorporationBinaryOpKind.ADD_EQ_BOUND;
770 case LOWER:
771 return IncorporationBinaryOpKind.ADD_LOWER_BOUND;
772 case UPPER:
773 return IncorporationBinaryOpKind.ADD_UPPER_BOUND;
774 default:
775 Assert.error("Can't get here!");
776 return null;
777 }
778 }
779
780 boolean doIncorporationOp(IncorporationBinaryOpKind opKind, Type op1, Type op2, Warner warn, Infer infer) {
781 IncorporationBinaryOp newOp = infer.new IncorporationBinaryOp(opKind, op1, op2);
782 Boolean res = infer.incorporationCache.get(newOp);
783 if (res == null) {
784 infer.incorporationCache.put(newOp, res = newOp.apply(warn));
785 }
786 return res;
753 } 787 }
754 } 788 }
755 789
756 /** incorporation steps to be executed when running in legacy mode */ 790 /** incorporation steps to be executed when running in legacy mode */
757 EnumSet<IncorporationStep> incorporationStepsLegacy = EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY); 791 EnumSet<IncorporationStep> incorporationStepsLegacy = EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY);
758 792
759 /** incorporation steps to be executed when running in graph mode */ 793 /** incorporation steps to be executed when running in graph mode */
760 EnumSet<IncorporationStep> incorporationStepsGraph = 794 EnumSet<IncorporationStep> incorporationStepsGraph =
761 EnumSet.complementOf(EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY)); 795 EnumSet.complementOf(EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY));
796
797 /**
798 * Three kinds of basic operation are supported as part of an incorporation step:
799 * (i) subtype check, (ii) same type check and (iii) bound addition (either
800 * upper/lower/eq bound).
801 */
802 enum IncorporationBinaryOpKind {
803 IS_SUBTYPE() {
804 @Override
805 boolean apply(Type op1, Type op2, Warner warn, Types types) {
806 return types.isSubtypeUnchecked(op1, op2, warn);
807 }
808 },
809 IS_SAME_TYPE() {
810 @Override
811 boolean apply(Type op1, Type op2, Warner warn, Types types) {
812 return types.isSameType(op1, op2);
813 }
814 },
815 ADD_UPPER_BOUND() {
816 @Override
817 boolean apply(Type op1, Type op2, Warner warn, Types types) {
818 UndetVar uv = (UndetVar)op1;
819 uv.addBound(InferenceBound.UPPER, op2, types);
820 return true;
821 }
822 },
823 ADD_LOWER_BOUND() {
824 @Override
825 boolean apply(Type op1, Type op2, Warner warn, Types types) {
826 UndetVar uv = (UndetVar)op1;
827 uv.addBound(InferenceBound.LOWER, op2, types);
828 return true;
829 }
830 },
831 ADD_EQ_BOUND() {
832 @Override
833 boolean apply(Type op1, Type op2, Warner warn, Types types) {
834 UndetVar uv = (UndetVar)op1;
835 uv.addBound(InferenceBound.EQ, op2, types);
836 return true;
837 }
838 };
839
840 abstract boolean apply(Type op1, Type op2, Warner warn, Types types);
841 }
842
843 /**
844 * This class encapsulates a basic incorporation operation; incorporation
845 * operations takes two type operands and a kind. Each operation performed
846 * during an incorporation round is stored in a cache, so that operations
847 * are not executed unnecessarily (which would potentially lead to adding
848 * same bounds over and over).
849 */
850 class IncorporationBinaryOp {
851
852 IncorporationBinaryOpKind opKind;
853 Type op1;
854 Type op2;
855
856 IncorporationBinaryOp(IncorporationBinaryOpKind opKind, Type op1, Type op2) {
857 this.opKind = opKind;
858 this.op1 = op1;
859 this.op2 = op2;
860 }
861
862 @Override
863 public boolean equals(Object o) {
864 if (!(o instanceof IncorporationBinaryOp)) {
865 return false;
866 } else {
867 IncorporationBinaryOp that = (IncorporationBinaryOp)o;
868 return opKind == that.opKind &&
869 types.isSameType(op1, that.op1, true) &&
870 types.isSameType(op2, that.op2, true);
871 }
872 }
873
874 @Override
875 public int hashCode() {
876 int result = opKind.hashCode();
877 result *= 127;
878 result += types.hashCode(op1);
879 result *= 127;
880 result += types.hashCode(op2);
881 return result;
882 }
883
884 boolean apply(Warner warn) {
885 return opKind.apply(op1, op2, warn, types);
886 }
887 }
888
889 /** an incorporation cache keeps track of all executed incorporation-related operations */
890 Map<IncorporationBinaryOp, Boolean> incorporationCache =
891 new HashMap<IncorporationBinaryOp, Boolean>();
762 892
763 /** 893 /**
764 * Make sure that the upper bounds we got so far lead to a solvable inference 894 * Make sure that the upper bounds we got so far lead to a solvable inference
765 * variable by making sure that a glb exists. 895 * variable by making sure that a glb exists.
766 */ 896 */
892 */ 1022 */
893 abstract class LeafSolver implements GraphStrategy { 1023 abstract class LeafSolver implements GraphStrategy {
894 public Node pickNode(InferenceGraph g) { 1024 public Node pickNode(InferenceGraph g) {
895 Assert.check(!g.nodes.isEmpty(), "No nodes to solve!"); 1025 Assert.check(!g.nodes.isEmpty(), "No nodes to solve!");
896 return g.nodes.get(0); 1026 return g.nodes.get(0);
1027 }
1028
1029 boolean isSubtype(Type s, Type t, Warner warn, Infer infer) {
1030 return doIncorporationOp(IncorporationBinaryOpKind.IS_SUBTYPE, s, t, warn, infer);
1031 }
1032
1033 boolean isSameType(Type s, Type t, Infer infer) {
1034 return doIncorporationOp(IncorporationBinaryOpKind.IS_SAME_TYPE, s, t, null, infer);
1035 }
1036
1037 void addBound(InferenceBound ib, UndetVar uv, Type b, Infer infer) {
1038 doIncorporationOp(opFor(ib), uv, b, null, infer);
1039 }
1040
1041 IncorporationBinaryOpKind opFor(InferenceBound boundKind) {
1042 switch (boundKind) {
1043 case EQ:
1044 return IncorporationBinaryOpKind.ADD_EQ_BOUND;
1045 case LOWER:
1046 return IncorporationBinaryOpKind.ADD_LOWER_BOUND;
1047 case UPPER:
1048 return IncorporationBinaryOpKind.ADD_UPPER_BOUND;
1049 default:
1050 Assert.error("Can't get here!");
1051 return null;
1052 }
1053 }
1054
1055 boolean doIncorporationOp(IncorporationBinaryOpKind opKind, Type op1, Type op2, Warner warn, Infer infer) {
1056 IncorporationBinaryOp newOp = infer.new IncorporationBinaryOp(opKind, op1, op2);
1057 Boolean res = infer.incorporationCache.get(newOp);
1058 if (res == null) {
1059 infer.incorporationCache.put(newOp, res = newOp.apply(warn));
1060 }
1061 return res;
897 } 1062 }
898 } 1063 }
899 1064
900 /** 1065 /**
901 * This solver uses an heuristic to pick the best leaf - the heuristic 1066 * This solver uses an heuristic to pick the best leaf - the heuristic

mercurial