Skip to content

RequirementMachine: Refactor nested type concretization #40536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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