3737using namespace swift ;
3838using namespace rewriting ;
3939
40+ // / Returns true if we have not processed this pair of rules before.
41+ bool PropertyMap::checkRulePairOnce (unsigned firstRuleID,
42+ unsigned secondRuleID) {
43+ return CheckedRulePairs.insert (
44+ std::make_pair (firstRuleID, secondRuleID)).second ;
45+ }
46+
4047unsigned RewriteSystem::recordRelation (Symbol lhs, Symbol rhs) {
4148 auto key = std::make_pair (lhs, rhs);
4249 auto found = RelationMap.find (key);
@@ -113,6 +120,24 @@ static void recordRelation(unsigned lhsRuleID, unsigned rhsRuleID,
113120 path);
114121}
115122
123+ static void recordConflict (Term key,
124+ unsigned existingRuleID,
125+ unsigned newRuleID,
126+ RewriteSystem &system) {
127+ // The GSB only dropped the new rule in the case of a conflicting
128+ // superclass requirement, so maintain that behavior here.
129+ auto &existingRule = system.getRule (existingRuleID);
130+ if (existingRule.isPropertyRule ()->getKind () !=
131+ Symbol::Kind::Superclass) {
132+ if (existingRule.getRHS ().size () == key.size ())
133+ existingRule.markConflicting ();
134+ }
135+
136+ auto &newRule = system.getRule (newRuleID);
137+ assert (newRule.getRHS ().size () == key.size ());
138+ newRule.markConflicting ();
139+ }
140+
116141// / This method takes a concrete type that was derived from a concrete type
117142// / produced by RewriteSystemBuilder::getConcreteSubstitutionSchema(),
118143// / either by extracting a structural sub-component or performing a (Swift AST)
@@ -385,10 +410,7 @@ static std::pair<Symbol, bool> unifySuperclasses(
385410
386411// / Record a protocol conformance, layout or superclass constraint on the given
387412// / key. Must be called in monotonically non-decreasing key order.
388- // /
389- // / If there was a conflict, returns the conflicting rule ID; otherwise
390- // / returns None.
391- Optional<unsigned > PropertyMap::addProperty (
413+ void PropertyMap::addProperty (
392414 Term key, Symbol property, unsigned ruleID,
393415 SmallVectorImpl<InducedRule> &inducedRules) {
394416 assert (property.isProperty ());
@@ -400,7 +422,7 @@ Optional<unsigned> PropertyMap::addProperty(
400422 case Symbol::Kind::Protocol:
401423 props->ConformsTo .push_back (property.getProtocol ());
402424 props->ConformsToRules .push_back (ruleID);
403- return None ;
425+ return ;
404426
405427 case Symbol::Kind::Layout: {
406428 auto newLayout = property.getLayoutConstraint ();
@@ -415,18 +437,27 @@ Optional<unsigned> PropertyMap::addProperty(
415437 auto mergedLayout = props->Layout .merge (property.getLayoutConstraint ());
416438
417439 // If the intersection is invalid, we have a conflict.
418- if (!mergedLayout->isKnownLayout ())
419- return props->LayoutRule ;
440+ if (!mergedLayout->isKnownLayout ()) {
441+ recordConflict (key, *props->LayoutRule , ruleID, System);
442+ return ;
443+ }
420444
421445 // If the intersection is equal to the existing layout requirement,
422446 // the new layout requirement is redundant.
423447 if (mergedLayout == props->Layout ) {
424- recordRelation (*props->LayoutRule , ruleID, System, inducedRules, debug);
448+ if (checkRulePairOnce (*props->LayoutRule , ruleID)) {
449+ recordRelation (*props->LayoutRule , ruleID, System,
450+ inducedRules, debug);
451+ }
425452
426453 // If the intersection is equal to the new layout requirement, the
427454 // existing layout requirement is redundant.
428455 } else if (mergedLayout == newLayout) {
429- recordRelation (ruleID, *props->LayoutRule , System, inducedRules, debug);
456+ if (checkRulePairOnce (*props->LayoutRule , ruleID)) {
457+ recordRelation (ruleID, *props->LayoutRule , System,
458+ inducedRules, debug);
459+ }
460+
430461 props->LayoutRule = ruleID;
431462 } else {
432463 llvm::errs () << " Arbitrary intersection of layout requirements is "
@@ -435,7 +466,7 @@ Optional<unsigned> PropertyMap::addProperty(
435466 }
436467 }
437468
438- return None ;
469+ return ;
439470 }
440471
441472 case Symbol::Kind::Superclass: {
@@ -451,11 +482,13 @@ Optional<unsigned> PropertyMap::addProperty(
451482 inducedRules, debug);
452483 props->Superclass = pair.first ;
453484 bool conflict = pair.second ;
454- if (conflict)
455- return props->SuperclassRule ;
485+ if (conflict) {
486+ recordConflict (key, *props->SuperclassRule , ruleID, System);
487+ return ;
488+ }
456489 }
457490
458- return None ;
491+ return ;
459492 }
460493
461494 case Symbol::Kind::ConcreteType: {
@@ -467,16 +500,18 @@ Optional<unsigned> PropertyMap::addProperty(
467500 bool conflict = unifyConcreteTypes (*props->ConcreteType , property,
468501 System.getRewriteContext (),
469502 inducedRules, debug);
470- if (conflict)
471- return props->ConcreteTypeRule ;
503+ if (conflict) {
504+ recordConflict (key, *props->ConcreteTypeRule , ruleID, System);
505+ return ;
506+ }
472507 }
473508
474- return None ;
509+ return ;
475510 }
476511
477512 case Symbol::Kind::ConcreteConformance:
478513 // FIXME
479- return None ;
514+ return ;
480515
481516 case Symbol::Kind::Name:
482517 case Symbol::Kind::GenericParam:
0 commit comments