@@ -111,6 +111,11 @@ static void recordRelation(Term key,
111111 (void ) system.addRule (lhs, rhs, &path);
112112}
113113
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.
114119static void recordConflict (Term key,
115120 unsigned existingRuleID,
116121 unsigned newRuleID,
@@ -605,53 +610,36 @@ void PropertyMap::processTypeDifference(const TypeDifference &difference,
605610 lhsRule.markSubstitutionSimplified ();
606611}
607612
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) {
632620 auto &rule = System.getRule (ruleID);
633621 assert (rule.getRHS () == key);
634622
635623 bool debug = Debug.contains (DebugFlags::ConcreteUnification);
636624
637- if (!props-> ConcreteType ) {
638- props-> ConcreteType = property;
639- props-> ConcreteTypeRule = ruleID;
625+ if (!existingProperty. hasValue () ) {
626+ existingProperty = property;
627+ existingRuleID = ruleID;
640628 return ;
641629 }
642630
643- assert (props-> ConcreteTypeRule .hasValue ());
631+ assert (existingRuleID .hasValue ());
644632
645633 if (debug) {
646- llvm::dbgs () << " % Unifying " << *props-> ConcreteType ;
647- llvm::dbgs () << " with " << property << " \n " ;
634+ llvm::dbgs () << " % Unifying " << *existingProperty
635+ << " with " << property << " \n " ;
648636 }
649637
650638 Optional<unsigned > lhsDifferenceID;
651639 Optional<unsigned > rhsDifferenceID;
652640
653641 bool conflict = System.computeTypeDifference (key,
654- *props-> ConcreteType , property,
642+ *existingProperty , property,
655643 lhsDifferenceID,
656644 rhsDifferenceID);
657645
@@ -660,7 +648,7 @@ void PropertyMap::addConcreteTypeProperty(
660648 if (debug) {
661649 llvm::dbgs () << " %% Concrete type conflict\n " ;
662650 }
663- recordConflict (key, *props-> ConcreteTypeRule , ruleID, System);
651+ recordConflict (key, *existingRuleID , ruleID, System);
664652 return ;
665653 }
666654
@@ -679,7 +667,7 @@ void PropertyMap::addConcreteTypeProperty(
679667 MutableTerm lhsTerm (key);
680668 lhsTerm.add (newProperty);
681669
682- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID)) {
670+ if (checkRulePairOnce (*existingRuleID , ruleID)) {
683671 assert (lhsDifference.RHS == rhsDifference.RHS );
684672
685673 if (debug) {
@@ -707,9 +695,9 @@ void PropertyMap::addConcreteTypeProperty(
707695 unsigned newRuleID = path.begin ()->getRuleID ();
708696
709697 // Process LHS -> (LHS ∧ RHS).
710- if (checkRulePairOnce (*props-> ConcreteTypeRule , newRuleID))
698+ if (checkRulePairOnce (*existingRuleID , newRuleID))
711699 processTypeDifference (lhsDifference, *lhsDifferenceID,
712- *props-> ConcreteTypeRule , newRuleID);
700+ *existingRuleID , newRuleID);
713701
714702 // Process RHS -> (LHS ∧ RHS).
715703 if (checkRulePairOnce (ruleID, newRuleID))
@@ -718,8 +706,8 @@ void PropertyMap::addConcreteTypeProperty(
718706
719707 // The new property is more specific, so update ConcreteType and
720708 // ConcreteTypeRule.
721- props-> ConcreteType = newProperty;
722- props-> ConcreteTypeRule = ruleID;
709+ existingProperty = newProperty;
710+ existingRuleID = ruleID;
723711
724712 return ;
725713 }
@@ -729,17 +717,17 @@ void PropertyMap::addConcreteTypeProperty(
729717 assert (!rhsDifferenceID);
730718
731719 const auto &lhsDifference = System.getTypeDifference (*lhsDifferenceID);
732- assert (*props-> ConcreteType == lhsDifference.LHS );
720+ assert (*existingProperty == lhsDifference.LHS );
733721 assert (property == lhsDifference.RHS );
734722
735- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID))
723+ if (checkRulePairOnce (*existingRuleID , ruleID))
736724 processTypeDifference (lhsDifference, *lhsDifferenceID,
737- *props-> ConcreteTypeRule , ruleID);
725+ *existingRuleID , ruleID);
738726
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;
743731
744732 return ;
745733 }
@@ -750,20 +738,20 @@ void PropertyMap::addConcreteTypeProperty(
750738
751739 const auto &rhsDifference = System.getTypeDifference (*rhsDifferenceID);
752740 assert (property == rhsDifference.LHS );
753- assert (*props-> ConcreteType == rhsDifference.RHS );
741+ assert (*existingProperty == rhsDifference.RHS );
754742
755- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID))
743+ if (checkRulePairOnce (*existingRuleID , ruleID))
756744 processTypeDifference (rhsDifference, *rhsDifferenceID,
757- ruleID, *props-> ConcreteTypeRule );
745+ ruleID, *existingRuleID );
758746
759- // The new property is less specific, so ConcreteType and ConcreteTypeRule
747+ // The new property is less specific, so existingProperty and existingRuleID
760748 // remain unchanged.
761749 return ;
762750 }
763751
764- assert (property == *props-> ConcreteType );
752+ assert (property == *existingProperty );
765753
766- if (*props-> ConcreteTypeRule != ruleID) {
754+ if (*existingRuleID != ruleID) {
767755 // If the rules are different but the concrete types are identical, then
768756 // the key is some term U.V, the existing rule is a rule of the form:
769757 //
@@ -777,17 +765,44 @@ void PropertyMap::addConcreteTypeProperty(
777765 // the symbol's substitutions.
778766 //
779767 // Since the new rule appears without context, it becomes redundant.
780- if (checkRulePairOnce (*props-> ConcreteTypeRule , ruleID)) {
768+ if (checkRulePairOnce (*existingRuleID , ruleID)) {
781769 RewritePath path;
782- buildRewritePathForUnifier (*props->ConcreteTypeRule , ruleID, System,
783- path);
770+ buildRewritePathForUnifier (*existingRuleID, ruleID, System, path);
784771 System.recordRewriteLoop (MutableTerm (rule.getLHS ()), path);
785772
786773 rule.markSubstitutionSimplified ();
787774 }
788775 }
789776}
790777
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+
791806// / Record a protocol conformance, layout or superclass constraint on the given
792807// / key. Must be called in monotonically non-decreasing key order.
793808void PropertyMap::addProperty (
0 commit comments