Skip to content

Commit 745acea

Browse files
committed
RequirementMachine: Introduce Rule::isIdentityConformanceRule()
1 parent f44926b commit 745acea

File tree

5 files changed

+39
-9
lines changed

5 files changed

+39
-9
lines changed

lib/AST/RequirementMachine/GeneratingConformances.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ void HomotopyGenerator::findProtocolConformanceRules(
8989
bool foundAny = false;
9090
for (unsigned ruleID : redundantRules) {
9191
const auto &rule = system.getRule(ruleID);
92+
93+
if (rule.isIdentityConformanceRule())
94+
continue;
95+
9296
if (auto *proto = rule.isProtocolConformanceRule()) {
9397
result[proto].first.push_back(ruleID);
9498
foundAny = true;
@@ -107,6 +111,10 @@ void HomotopyGenerator::findProtocolConformanceRules(
107111
switch (step.Kind) {
108112
case RewriteStep::ApplyRewriteRule: {
109113
const auto &rule = system.getRule(step.RuleID);
114+
115+
if (rule.isIdentityConformanceRule())
116+
break;
117+
110118
if (auto *proto = rule.isProtocolConformanceRule()) {
111119
if (step.StartOffset > 0 &&
112120
step.EndOffset == 0) {
@@ -157,7 +165,13 @@ RewriteSystem::decomposeTermIntoConformanceRuleLeftHandSides(
157165
"Canonical conformance term should simplify in one step");
158166

159167
const auto &step = *steps.begin();
160-
assert(getRule(step.RuleID).isProtocolConformanceRule());
168+
169+
#ifndef NDEBUG
170+
const auto &rule = getRule(step.RuleID);
171+
assert(rule.isProtocolConformanceRule());
172+
assert(!rule.isIdentityConformanceRule());
173+
#endif
174+
161175
assert(step.Kind == RewriteStep::ApplyRewriteRule);
162176
assert(step.EndOffset == 0);
163177
assert(!step.Inverse);
@@ -183,6 +197,7 @@ RewriteSystem::decomposeTermIntoConformanceRuleLeftHandSides(
183197
SmallVectorImpl<unsigned> &result) const {
184198
const auto &rule = getRule(ruleID);
185199
assert(rule.isProtocolConformanceRule());
200+
assert(!rule.isIdentityConformanceRule());
186201

187202
// Compute domain(V).
188203
const auto &lhs = rule.getLHS();
@@ -596,6 +611,9 @@ void RewriteSystem::computeGeneratingConformances(
596611
// can be expressed as itself.
597612
for (unsigned ruleID : indices(Rules)) {
598613
const auto &rule = getRule(ruleID);
614+
if (rule.isPermanent())
615+
continue;
616+
599617
if (rule.isRedundant())
600618
continue;
601619

@@ -706,4 +724,4 @@ void RewriteSystem::computeGeneratingConformances(
706724
llvm::dbgs() << "- " << getRule(pair.first) << "\n";
707725
}
708726
}
709-
}
727+
}

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,10 @@ void RewriteSystem::verifyRedundantConformances(
10871087
llvm::DenseSet<unsigned> redundantConformances) const {
10881088
for (unsigned ruleID : redundantConformances) {
10891089
const auto &rule = getRule(ruleID);
1090+
assert(!rule.isPermanent() &&
1091+
"Permanent rule cannot be redundant");
1092+
assert(!rule.isIdentityConformanceRule() &&
1093+
"Identity conformance cannot be redundant");
10901094
assert(rule.isProtocolConformanceRule() &&
10911095
"Redundant conformance is not a conformance rule?");
10921096

lib/AST/RequirementMachine/PropertyMap.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ RewriteSystem::buildPropertyMap(PropertyMap &map,
334334
if (rule.isSimplified())
335335
continue;
336336

337+
if (rule.isPermanent())
338+
continue;
339+
337340
// Collect all rules of the form T.[p] => T where T is canonical.
338341
auto property = rule.isPropertyRule();
339342
if (!property)

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,6 @@ Optional<Symbol> Rule::isPropertyRule() const {
4040
if (!std::equal(RHS.begin(), RHS.end(), LHS.begin()))
4141
return None;
4242

43-
// A same-type requirement of the form 'Self.Foo == Self' can induce a
44-
// conformance rule [P].[P] => [P]. Don't consider this a property-like
45-
// rule, since it messes up the generating conformances algorithm and
46-
// doesn't mean anything useful anyway.
47-
if (RHS.size() == 1 && RHS[0] == LHS[1])
48-
return None;
49-
5043
return property;
5144
}
5245

@@ -61,6 +54,16 @@ const ProtocolDecl *Rule::isProtocolConformanceRule() const {
6154
return nullptr;
6255
}
6356

57+
/// If this is a rule of the form [P].[P] => [P] where [P] is a protocol
58+
/// symbol, return true, otherwise return false.
59+
bool Rule::isIdentityConformanceRule() const {
60+
return (LHS.size() == 2 &&
61+
RHS.size() == 1 &&
62+
LHS[0] == RHS[0] &&
63+
LHS[0] == LHS[1] &&
64+
LHS[0].getKind() == Symbol::Kind::Protocol);
65+
}
66+
6467
/// If this is a rule of the form [P].[Q] => [P] where [P] and [Q] are
6568
/// protocol symbols, return true, otherwise return false.
6669
bool Rule::isProtocolRefinementRule() const {

lib/AST/RequirementMachine/RewriteSystem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ class Rule final {
7979

8080
const ProtocolDecl *isProtocolConformanceRule() const;
8181

82+
bool isIdentityConformanceRule() const;
83+
8284
bool isProtocolRefinementRule() const;
8385

8486
/// See above for an explanation.

0 commit comments

Comments
 (0)