Skip to content
Merged
15 changes: 10 additions & 5 deletions lib/AST/RequirementMachine/HomotopyReduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,16 +523,19 @@ void RewriteSystem::minimizeRewriteSystem() {

/// In a conformance-valid rewrite system, any rule with unresolved symbols on
/// the left or right hand side should have been simplified by another rule.
bool RewriteSystem::hasNonRedundantUnresolvedRules() const {
bool RewriteSystem::hadError() const {
assert(Complete);
assert(Minimized);

for (const auto &rule : Rules) {
if (!rule.isRedundant() &&
!rule.isPermanent() &&
rule.containsUnresolvedSymbols()) {
if (rule.isPermanent())
continue;

if (rule.isConflicting())
return true;

if (!rule.isRedundant() && rule.containsUnresolvedSymbols())
return true;
}
}

return false;
Expand All @@ -555,6 +558,7 @@ RewriteSystem::getMinimizedProtocolRules(

if (rule.isPermanent() ||
rule.isRedundant() ||
rule.isConflicting() ||
rule.containsUnresolvedSymbols()) {
continue;
}
Expand Down Expand Up @@ -584,6 +588,7 @@ RewriteSystem::getMinimizedGenericSignatureRules() const {

if (rule.isPermanent() ||
rule.isRedundant() ||
rule.isConflicting() ||
rule.containsUnresolvedSymbols()) {
continue;
}
Expand Down
4 changes: 3 additions & 1 deletion lib/AST/RequirementMachine/KnuthBendix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ RewriteSystem::computeConfluentCompletion(unsigned maxIterations,
}
}

simplifyRewriteSystem();
simplifyLeftHandSides();

assert(resolvedCriticalPairs.size() == resolvedPaths.size());

Expand Down Expand Up @@ -629,6 +629,8 @@ RewriteSystem::computeConfluentCompletion(unsigned maxIterations,
resolvedPaths.clear();
resolvedLoops.clear();

simplifyRightHandSidesAndSubstitutions();

// If the added rules merged any associated types, process the merges now
// before we continue with the completion procedure. This is important
// to perform incrementally since merging is required to repair confluence
Expand Down
16 changes: 8 additions & 8 deletions lib/AST/RequirementMachine/PropertyMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,15 @@ void PropertyMap::clear() {

/// Record a protocol conformance, layout or superclass constraint on the given
/// key. Must be called in monotonically non-decreasing key order.
void PropertyMap::addProperty(
bool PropertyMap::addProperty(
Term key, Symbol property, unsigned ruleID,
SmallVectorImpl<InducedRule> &inducedRules) {
assert(property.isProperty());
assert(*System.getRule(ruleID).isPropertyRule() == property);
auto *props = getOrCreateProperties(key);
props->addProperty(property, ruleID, Context,
inducedRules, Debug.contains(DebugFlags::ConcreteUnification));
bool debug = Debug.contains(DebugFlags::ConcreteUnification);
return props->addProperty(property, ruleID, Context,
inducedRules, debug);
}

/// Build the property map from all rules of the form T.[p] => T, where
Expand Down Expand Up @@ -375,7 +376,10 @@ PropertyMap::buildPropertyMap(unsigned maxIterations,

for (const auto &bucket : properties) {
for (auto property : bucket) {
addProperty(property.key, property.symbol, property.ruleID, inducedRules);
bool conflict = addProperty(property.key, property.symbol,
property.ruleID, inducedRules);
if (conflict)
System.getRule(property.ruleID).markConflicting();
}
}

Expand All @@ -388,10 +392,6 @@ PropertyMap::buildPropertyMap(unsigned maxIterations,
// the concrete type witnesses in the concrete type's conformance.
concretizeNestedTypesFromConcreteParents(inducedRules);

// Finally, introduce concrete conformance rules, relating conformance rules
// to concrete type and superclass rules.
recordConcreteConformanceRules(inducedRules);

// Some of the induced rules might be trivial; only count the induced rules
// where the left hand side is not already equivalent to the right hand side.
unsigned addedNewRules = 0;
Expand Down
26 changes: 17 additions & 9 deletions lib/AST/RequirementMachine/PropertyMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class PropertyBag {

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

void addProperty(Symbol property,
bool addProperty(Symbol property,
unsigned ruleID,
RewriteContext &ctx,
SmallVectorImpl<InducedRule> &inducedRules,
Expand Down Expand Up @@ -202,32 +202,40 @@ class PropertyMap {

private:
void clear();
void addProperty(Term key, Symbol property, unsigned ruleID,
bool addProperty(Term key, Symbol property, unsigned ruleID,
SmallVectorImpl<InducedRule> &inducedRules);

void computeConcreteTypeInDomainMap();
void concretizeNestedTypesFromConcreteParents(
SmallVectorImpl<InducedRule> &inducedRules) const;
SmallVectorImpl<InducedRule> &inducedRules);

void concretizeNestedTypesFromConcreteParent(
Term key, RequirementKind requirementKind,
CanType concreteType, ArrayRef<Term> substitutions,
unsigned concreteRuleID,
CanType concreteType,
ArrayRef<Term> substitutions,
ArrayRef<unsigned> conformsToRules,
ArrayRef<const ProtocolDecl *> conformsTo,
llvm::TinyPtrVector<ProtocolConformance *> &conformances,
SmallVectorImpl<InducedRule> &inducedRules);

void concretizeTypeWitnessInConformance(
Term key, RequirementKind requirementKind,
Symbol concreteConformanceSymbol,
ProtocolConformance *concrete,
AssociatedTypeDecl *assocType,
SmallVectorImpl<InducedRule> &inducedRules) const;

MutableTerm computeConstraintTermForTypeWitness(
Term key, CanType concreteType, CanType typeWitness,
const MutableTerm &subjectType, ArrayRef<Term> substitutions) const;

void recordConcreteConformanceRules(
SmallVectorImpl<InducedRule> &inducedRules);

void recordConcreteConformanceRule(
unsigned concreteRuleID,
unsigned conformanceRuleID,
const ProtocolDecl *proto,
SmallVectorImpl<InducedRule> &inducedRules);
RequirementKind requirementKind,
Symbol concreteConformanceSymbol,
SmallVectorImpl<InducedRule> &inducedRules) const;

void verify() const;
};
Expand Down
Loading