37
37
using namespace swift ;
38
38
using namespace rewriting ;
39
39
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
+
40
47
unsigned RewriteSystem::recordRelation (Symbol lhs, Symbol rhs) {
41
48
auto key = std::make_pair (lhs, rhs);
42
49
auto found = RelationMap.find (key);
@@ -113,6 +120,24 @@ static void recordRelation(unsigned lhsRuleID, unsigned rhsRuleID,
113
120
path);
114
121
}
115
122
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
+
116
141
// / This method takes a concrete type that was derived from a concrete type
117
142
// / produced by RewriteSystemBuilder::getConcreteSubstitutionSchema(),
118
143
// / either by extracting a structural sub-component or performing a (Swift AST)
@@ -385,10 +410,7 @@ static std::pair<Symbol, bool> unifySuperclasses(
385
410
386
411
// / Record a protocol conformance, layout or superclass constraint on the given
387
412
// / 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 (
392
414
Term key, Symbol property, unsigned ruleID,
393
415
SmallVectorImpl<InducedRule> &inducedRules) {
394
416
assert (property.isProperty ());
@@ -400,7 +422,7 @@ Optional<unsigned> PropertyMap::addProperty(
400
422
case Symbol::Kind::Protocol:
401
423
props->ConformsTo .push_back (property.getProtocol ());
402
424
props->ConformsToRules .push_back (ruleID);
403
- return None ;
425
+ return ;
404
426
405
427
case Symbol::Kind::Layout: {
406
428
auto newLayout = property.getLayoutConstraint ();
@@ -415,18 +437,27 @@ Optional<unsigned> PropertyMap::addProperty(
415
437
auto mergedLayout = props->Layout .merge (property.getLayoutConstraint ());
416
438
417
439
// 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
+ }
420
444
421
445
// If the intersection is equal to the existing layout requirement,
422
446
// the new layout requirement is redundant.
423
447
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
+ }
425
452
426
453
// If the intersection is equal to the new layout requirement, the
427
454
// existing layout requirement is redundant.
428
455
} 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
+
430
461
props->LayoutRule = ruleID;
431
462
} else {
432
463
llvm::errs () << " Arbitrary intersection of layout requirements is "
@@ -435,7 +466,7 @@ Optional<unsigned> PropertyMap::addProperty(
435
466
}
436
467
}
437
468
438
- return None ;
469
+ return ;
439
470
}
440
471
441
472
case Symbol::Kind::Superclass: {
@@ -451,11 +482,13 @@ Optional<unsigned> PropertyMap::addProperty(
451
482
inducedRules, debug);
452
483
props->Superclass = pair.first ;
453
484
bool conflict = pair.second ;
454
- if (conflict)
455
- return props->SuperclassRule ;
485
+ if (conflict) {
486
+ recordConflict (key, *props->SuperclassRule , ruleID, System);
487
+ return ;
488
+ }
456
489
}
457
490
458
- return None ;
491
+ return ;
459
492
}
460
493
461
494
case Symbol::Kind::ConcreteType: {
@@ -467,16 +500,18 @@ Optional<unsigned> PropertyMap::addProperty(
467
500
bool conflict = unifyConcreteTypes (*props->ConcreteType , property,
468
501
System.getRewriteContext (),
469
502
inducedRules, debug);
470
- if (conflict)
471
- return props->ConcreteTypeRule ;
503
+ if (conflict) {
504
+ recordConflict (key, *props->ConcreteTypeRule , ruleID, System);
505
+ return ;
506
+ }
472
507
}
473
508
474
- return None ;
509
+ return ;
475
510
}
476
511
477
512
case Symbol::Kind::ConcreteConformance:
478
513
// FIXME
479
- return None ;
514
+ return ;
480
515
481
516
case Symbol::Kind::Name:
482
517
case Symbol::Kind::GenericParam:
0 commit comments