@@ -119,9 +119,37 @@ static void recordRelation(Term key,
119119 (void ) system.addRule (lhs, rhs, &path);
120120}
121121
122+ // / Given two property rules that conflict because no concrete type
123+ // / can satisfy both, mark one or both rules conflicting.
124+ // /
125+ // / The right hand side of one rule must be a suffix of the other
126+ // / (in which case the longer of the two rules is conflicting) or
127+ // / the right hand sides are equal (in which case both will be
128+ // / conflicting).
122129void RewriteSystem::recordConflict (unsigned existingRuleID,
123130 unsigned newRuleID) {
124131 ConflictingRules.emplace_back (existingRuleID, newRuleID);
132+
133+ auto &existingRule = getRule (existingRuleID);
134+ auto &newRule = getRule (newRuleID);
135+
136+ if (Debug.contains (DebugFlags::ConflictingRules)) {
137+ llvm::dbgs () << " Conflicting rules:\n " ;
138+ llvm::dbgs () << " - " << existingRule << " \n " ;
139+ llvm::dbgs () << " - " << newRule << " \n " ;
140+ }
141+
142+ // The identity conformance rule ([P].[P] => [P]) will conflict with
143+ // a concrete type requirement in an invalid protocol declaration
144+ // where 'Self' is constrained to a type that does not conform to
145+ // the protocol. This rule is permanent, so don't mark it as
146+ // conflicting in this case.
147+ if (!existingRule.isIdentityConformanceRule () &&
148+ existingRule.getRHS ().size () >= newRule.getRHS ().size ())
149+ existingRule.markConflicting ();
150+ if (!newRule.isIdentityConformanceRule () &&
151+ newRule.getRHS ().size () >= existingRule.getRHS ().size ())
152+ newRule.markConflicting ();
125153}
126154
127155void PropertyMap::addConformanceProperty (
0 commit comments