Skip to content

Commit 5c11f36

Browse files
committed
RequirementMachine: Mark rules as conflicting more aggressively
1 parent f4ff260 commit 5c11f36

File tree

3 files changed

+49
-26
lines changed

3 files changed

+49
-26
lines changed

lib/AST/RequirementMachine/PropertyMap.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,10 @@ void PropertyMap::clear() {
309309

310310
/// Record a protocol conformance, layout or superclass constraint on the given
311311
/// key. Must be called in monotonically non-decreasing key order.
312-
bool PropertyMap::addProperty(
312+
///
313+
/// If there was a conflict, returns the conflicting rule ID; otherwise
314+
/// returns None.
315+
Optional<unsigned> PropertyMap::addProperty(
313316
Term key, Symbol property, unsigned ruleID,
314317
SmallVectorImpl<InducedRule> &inducedRules) {
315318
assert(property.isProperty());
@@ -376,10 +379,22 @@ PropertyMap::buildPropertyMap(unsigned maxIterations,
376379

377380
for (const auto &bucket : properties) {
378381
for (auto property : bucket) {
379-
bool conflict = addProperty(property.key, property.symbol,
380-
property.ruleID, inducedRules);
381-
if (conflict)
382-
System.getRule(property.ruleID).markConflicting();
382+
auto existingRuleID = addProperty(property.key, property.symbol,
383+
property.ruleID, inducedRules);
384+
if (existingRuleID) {
385+
// The GSB only dropped the new rule in the case of a conflicting
386+
// superclass requirement, so maintain that behavior here.
387+
auto &existingRule = System.getRule(*existingRuleID);
388+
if (existingRule.isPropertyRule()->getKind() !=
389+
Symbol::Kind::Superclass) {
390+
if (existingRule.getRHS().size() == property.key.size())
391+
existingRule.markConflicting();
392+
}
393+
394+
auto &newRule = System.getRule(property.ruleID);
395+
assert(newRule.getRHS().size() == property.key.size());
396+
newRule.markConflicting();
397+
}
383398
}
384399
}
385400

lib/AST/RequirementMachine/PropertyMap.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,11 @@ class PropertyBag {
101101

102102
explicit PropertyBag(Term key) : Key(key) {}
103103

104-
bool addProperty(Symbol property,
105-
unsigned ruleID,
106-
RewriteContext &ctx,
107-
SmallVectorImpl<InducedRule> &inducedRules,
108-
bool debug);
104+
Optional<unsigned> addProperty(Symbol property,
105+
unsigned ruleID,
106+
RewriteContext &ctx,
107+
SmallVectorImpl<InducedRule> &inducedRules,
108+
bool debug);
109109
void copyPropertiesFrom(const PropertyBag *next,
110110
RewriteContext &ctx);
111111

@@ -204,8 +204,9 @@ class PropertyMap {
204204

205205
private:
206206
void clear();
207-
bool addProperty(Term key, Symbol property, unsigned ruleID,
208-
SmallVectorImpl<InducedRule> &inducedRules);
207+
Optional<unsigned>
208+
addProperty(Term key, Symbol property, unsigned ruleID,
209+
SmallVectorImpl<InducedRule> &inducedRules);
209210

210211
void computeConcreteTypeInDomainMap();
211212
void concretizeNestedTypesFromConcreteParents(

lib/AST/RequirementMachine/PropertyUnification.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,9 @@ static std::pair<Symbol, bool> unifySuperclasses(
307307
return std::make_pair(rhs, false);
308308
}
309309

310-
/// Returns true if there was a conflict.
311-
bool PropertyBag::addProperty(
310+
/// Returns the old conflicting rule ID if there was a conflict,
311+
/// otherwise returns None.
312+
Optional<unsigned> PropertyBag::addProperty(
312313
Symbol property, unsigned ruleID, RewriteContext &ctx,
313314
SmallVectorImpl<InducedRule> &inducedRules,
314315
bool debug) {
@@ -317,19 +318,20 @@ bool PropertyBag::addProperty(
317318
case Symbol::Kind::Protocol:
318319
ConformsTo.push_back(property.getProtocol());
319320
ConformsToRules.push_back(ruleID);
320-
return false;
321+
return None;
321322

322323
case Symbol::Kind::Layout:
323324
if (!Layout) {
324325
Layout = property.getLayoutConstraint();
325326
LayoutRule = ruleID;
326327
} else {
328+
assert(LayoutRule.hasValue());
327329
Layout = Layout.merge(property.getLayoutConstraint());
328330
if (!Layout->isKnownLayout())
329-
return true;
331+
return LayoutRule;
330332
}
331333

332-
return false;
334+
return None;
333335

334336
case Symbol::Kind::Superclass: {
335337
// FIXME: Also handle superclass vs concrete
@@ -338,34 +340,36 @@ bool PropertyBag::addProperty(
338340
Superclass = property;
339341
SuperclassRule = ruleID;
340342
} else {
343+
assert(SuperclassRule.hasValue());
341344
auto pair = unifySuperclasses(*Superclass, property,
342345
ctx, inducedRules, debug);
343346
Superclass = pair.first;
344347
bool conflict = pair.second;
345348
if (conflict)
346-
return true;
349+
return SuperclassRule;
347350
}
348351

349-
return false;
352+
return None;
350353
}
351354

352355
case Symbol::Kind::ConcreteType: {
353356
if (!ConcreteType) {
354357
ConcreteType = property;
355358
ConcreteTypeRule = ruleID;
356359
} else {
360+
assert(ConcreteTypeRule.hasValue());
357361
bool conflict = unifyConcreteTypes(*ConcreteType, property,
358362
ctx, inducedRules, debug);
359363
if (conflict)
360-
return true;
364+
return ConcreteTypeRule;
361365
}
362366

363-
return false;
367+
return None;
364368
}
365369

366370
case Symbol::Kind::ConcreteConformance:
367371
// FIXME
368-
return false;
372+
return None;
369373

370374
case Symbol::Kind::Name:
371375
case Symbol::Kind::GenericParam:
@@ -533,10 +537,13 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
533537
// With concrete types, a missing conformance is a conflict.
534538
if (requirementKind == RequirementKind::SameType) {
535539
// FIXME: Diagnose conflict
536-
//
537-
// FIXME: We should mark the more specific rule of the two
538-
// as conflicting.
539-
System.getRule(conformanceRuleID).markConflicting();
540+
auto &concreteRule = System.getRule(concreteRuleID);
541+
if (concreteRule.getRHS().size() == key.size())
542+
concreteRule.markConflicting();
543+
544+
auto &conformanceRule = System.getRule(conformanceRuleID);
545+
if (conformanceRule.getRHS().size() == key.size())
546+
conformanceRule.markConflicting();
540547
}
541548

542549
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {

0 commit comments

Comments
 (0)