@@ -111,6 +111,11 @@ static void recordRelation(Term key,
111
111
(void ) system.addRule (lhs, rhs, &path);
112
112
}
113
113
114
+ // / Given a term T == U.V, an existing rule (V.[C] => V) and a new rule
115
+ // / (U.V.[D] => U.V) where [C] and [D] are understood to be two property
116
+ // / symbols in conflict with each other, mark the new rule as conflicting,
117
+ // / and if the existing rule applies to the entire term T (that is, if
118
+ // / |U| == 0) also mark the existing rule as conflicting.
114
119
static void recordConflict (Term key,
115
120
unsigned existingRuleID,
116
121
unsigned newRuleID,
@@ -605,53 +610,36 @@ void PropertyMap::processTypeDifference(const TypeDifference &difference,
605
610
lhsRule.markSubstitutionSimplified ();
606
611
}
607
612
608
- // / When a type parameter has two concrete types, we have to unify the
609
- // / type constructor arguments.
610
- // /
611
- // / For example, suppose that we have two concrete same-type requirements:
612
- // /
613
- // / T == Foo<X.Y, Z, String>
614
- // / T == Foo<Int, A.B, W>
615
- // /
616
- // / These lower to the following two rules:
617
- // /
618
- // / T.[concrete: Foo<τ_0_0, τ_0_1, String> with {X.Y, Z}] => T
619
- // / T.[concrete: Foo<Int, τ_0_0, τ_0_1> with {A.B, W}] => T
620
- // /
621
- // / The two concrete type symbols will be added to the property bag of 'T',
622
- // / and we will eventually end up in this method, where we will generate three
623
- // / induced rules:
624
- // /
625
- // / X.Y.[concrete: Int] => X.Y
626
- // / A.B => Z
627
- // / W.[concrete: String] => W
628
- void PropertyMap::addConcreteTypeProperty (
629
- Term key, Symbol property, unsigned ruleID) {
630
- auto *props = getOrCreateProperties (key);
631
-
613
+ // / Utility used by addSuperclassProperty() and addConcreteTypeProperty().
614
+ void PropertyMap::unifyConcreteTypes (
615
+ Term key,
616
+ Optional<Symbol> &existingProperty,
617
+ Optional<unsigned > &existingRuleID,
618
+ Symbol property,
619
+ unsigned ruleID) {
632
620
auto &rule = System.getRule (ruleID);
633
621
assert (rule.getRHS () == key);
634
622
635
623
bool debug = Debug.contains (DebugFlags::ConcreteUnification);
636
624
637
- if (!props-> ConcreteType ) {
638
- props-> ConcreteType = property;
639
- props-> ConcreteTypeRule = ruleID;
625
+ if (!existingProperty. hasValue () ) {
626
+ existingProperty = property;
627
+ existingRuleID = ruleID;
640
628
return ;
641
629
}
642
630
643
- assert (props-> ConcreteTypeRule .hasValue ());
631
+ assert (existingRuleID .hasValue ());
644
632
645
633
if (debug) {
646
- llvm::dbgs () << " % Unifying " << *props-> ConcreteType ;
647
- llvm::dbgs () << " with " << property << " \n " ;
634
+ llvm::dbgs () << " % Unifying " << *existingProperty
635
+ << " with " << property << " \n " ;
648
636
}
649
637
650
638
Optional<unsigned > lhsDifferenceID;
651
639
Optional<unsigned > rhsDifferenceID;
652
640
653
641
bool conflict = System.computeTypeDifference (key,
654
- *props-> ConcreteType , property,
642
+ *existingProperty , property,
655
643
lhsDifferenceID,
656
644
rhsDifferenceID);
657
645
@@ -660,7 +648,7 @@ void PropertyMap::addConcreteTypeProperty(
660
648
if (debug) {
661
649
llvm::dbgs () << " %% Concrete type conflict\n " ;
662
650
}
663
- recordConflict (key, *props-> ConcreteTypeRule , ruleID, System);
651
+ recordConflict (key, *existingRuleID , ruleID, System);
664
652
return ;
665
653
}
666
654
@@ -679,7 +667,7 @@ void PropertyMap::addConcreteTypeProperty(
679
667
MutableTerm lhsTerm (key);
680
668
lhsTerm.add (newProperty);
681
669
682
- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID)) {
670
+ if (checkRulePairOnce (*existingRuleID , ruleID)) {
683
671
assert (lhsDifference.RHS == rhsDifference.RHS );
684
672
685
673
if (debug) {
@@ -707,9 +695,9 @@ void PropertyMap::addConcreteTypeProperty(
707
695
unsigned newRuleID = path.begin ()->getRuleID ();
708
696
709
697
// Process LHS -> (LHS ∧ RHS).
710
- if (checkRulePairOnce (*props-> ConcreteTypeRule , newRuleID))
698
+ if (checkRulePairOnce (*existingRuleID , newRuleID))
711
699
processTypeDifference (lhsDifference, *lhsDifferenceID,
712
- *props-> ConcreteTypeRule , newRuleID);
700
+ *existingRuleID , newRuleID);
713
701
714
702
// Process RHS -> (LHS ∧ RHS).
715
703
if (checkRulePairOnce (ruleID, newRuleID))
@@ -718,8 +706,8 @@ void PropertyMap::addConcreteTypeProperty(
718
706
719
707
// The new property is more specific, so update ConcreteType and
720
708
// ConcreteTypeRule.
721
- props-> ConcreteType = newProperty;
722
- props-> ConcreteTypeRule = ruleID;
709
+ existingProperty = newProperty;
710
+ existingRuleID = ruleID;
723
711
724
712
return ;
725
713
}
@@ -729,17 +717,17 @@ void PropertyMap::addConcreteTypeProperty(
729
717
assert (!rhsDifferenceID);
730
718
731
719
const auto &lhsDifference = System.getTypeDifference (*lhsDifferenceID);
732
- assert (*props-> ConcreteType == lhsDifference.LHS );
720
+ assert (*existingProperty == lhsDifference.LHS );
733
721
assert (property == lhsDifference.RHS );
734
722
735
- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID))
723
+ if (checkRulePairOnce (*existingRuleID , ruleID))
736
724
processTypeDifference (lhsDifference, *lhsDifferenceID,
737
- *props-> ConcreteTypeRule , ruleID);
725
+ *existingRuleID , ruleID);
738
726
739
- // The new property is more specific, so update ConcreteType and
740
- // ConcreteTypeRule .
741
- props-> ConcreteType = property;
742
- props-> ConcreteTypeRule = ruleID;
727
+ // The new property is more specific, so update existingProperty and
728
+ // existingRuleID .
729
+ existingProperty = property;
730
+ existingRuleID = ruleID;
743
731
744
732
return ;
745
733
}
@@ -750,20 +738,20 @@ void PropertyMap::addConcreteTypeProperty(
750
738
751
739
const auto &rhsDifference = System.getTypeDifference (*rhsDifferenceID);
752
740
assert (property == rhsDifference.LHS );
753
- assert (*props-> ConcreteType == rhsDifference.RHS );
741
+ assert (*existingProperty == rhsDifference.RHS );
754
742
755
- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID))
743
+ if (checkRulePairOnce (*existingRuleID , ruleID))
756
744
processTypeDifference (rhsDifference, *rhsDifferenceID,
757
- ruleID, *props-> ConcreteTypeRule );
745
+ ruleID, *existingRuleID );
758
746
759
- // The new property is less specific, so ConcreteType and ConcreteTypeRule
747
+ // The new property is less specific, so existingProperty and existingRuleID
760
748
// remain unchanged.
761
749
return ;
762
750
}
763
751
764
- assert (property == *props-> ConcreteType );
752
+ assert (property == *existingProperty );
765
753
766
- if (*props-> ConcreteTypeRule != ruleID) {
754
+ if (*existingRuleID != ruleID) {
767
755
// If the rules are different but the concrete types are identical, then
768
756
// the key is some term U.V, the existing rule is a rule of the form:
769
757
//
@@ -777,17 +765,44 @@ void PropertyMap::addConcreteTypeProperty(
777
765
// the symbol's substitutions.
778
766
//
779
767
// Since the new rule appears without context, it becomes redundant.
780
- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID)) {
768
+ if (checkRulePairOnce (*existingRuleID , ruleID)) {
781
769
RewritePath path;
782
- buildRewritePathForUnifier (*props->ConcreteTypeRule , ruleID, System,
783
- path);
770
+ buildRewritePathForUnifier (*existingRuleID, ruleID, System, path);
784
771
System.recordRewriteLoop (MutableTerm (rule.getLHS ()), path);
785
772
786
773
rule.markSubstitutionSimplified ();
787
774
}
788
775
}
789
776
}
790
777
778
+ // / When a type parameter has two concrete types, we have to unify the
779
+ // / type constructor arguments.
780
+ // /
781
+ // / For example, suppose that we have two concrete same-type requirements:
782
+ // /
783
+ // / T == Foo<X.Y, Z, String>
784
+ // / T == Foo<Int, A.B, W>
785
+ // /
786
+ // / These lower to the following two rules:
787
+ // /
788
+ // / T.[concrete: Foo<τ_0_0, τ_0_1, String> with {X.Y, Z}] => T
789
+ // / T.[concrete: Foo<Int, τ_0_0, τ_0_1> with {A.B, W}] => T
790
+ // /
791
+ // / The two concrete type symbols will be added to the property bag of 'T',
792
+ // / and we will eventually end up in this method, where we will generate three
793
+ // / induced rules:
794
+ // /
795
+ // / X.Y.[concrete: Int] => X.Y
796
+ // / A.B => Z
797
+ // / W.[concrete: String] => W
798
+ void PropertyMap::addConcreteTypeProperty (
799
+ Term key, Symbol property, unsigned ruleID) {
800
+ auto *props = getOrCreateProperties (key);
801
+
802
+ unifyConcreteTypes (key, props->ConcreteType , props->ConcreteTypeRule ,
803
+ property, ruleID);
804
+ }
805
+
791
806
// / Record a protocol conformance, layout or superclass constraint on the given
792
807
// / key. Must be called in monotonically non-decreasing key order.
793
808
void PropertyMap::addProperty (
0 commit comments