Skip to content

Commit c5cef95

Browse files
committed
RequirementMachine: Minimal conformances collects protocol refinement rules from all minimization domains
1 parent 6c0ccfc commit c5cef95

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

lib/AST/RequirementMachine/MinimalConformances.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,18 @@ class MinimalConformances {
159159

160160
DebugOptions Debug;
161161

162-
// All conformance rules, sorted by (isExplicit(), getLHS()), with non-explicit
163-
// rules with longer left hand sides coming first.
162+
// All conformance rules in the current minimization domain, sorted by
163+
// (isExplicit(), getLHS()), with non-explicit rules with longer left hand
164+
// sides coming first.
164165
//
165166
// The idea here is that we want less canonical rules to be eliminated first,
166167
// but we prefer to eliminate non-explicit rules, in an attempt to keep protocol
167168
// conformance rules in the same protocol as they were originally defined in.
168169
SmallVector<unsigned, 4> ConformanceRules;
169170

170-
// Maps a conformance rule to a conformance path deriving the subject type's
171-
// base type. For example, consider the following conformance rule:
171+
// Maps a conformance rule in the current minimization domain to a conformance
172+
// path deriving the subject type's base type. For example, consider the
173+
// following conformance rule:
172174
//
173175
// T.[P:A].[Q:B].[R] => T.[P:A].[Q:B]
174176
//
@@ -177,15 +179,17 @@ class MinimalConformances {
177179
// path for the term T.[P:A].[Q], known as the 'parent path'.
178180
llvm::MapVector<unsigned, SmallVector<unsigned, 2>> ParentPaths;
179181

180-
// Maps a conformance rule to a list of paths. Each path in the list is a unique
181-
// derivation of the conformance in terms of other conformance rules.
182+
// Maps a conformance rule in the current minimization domain to a list of paths.
183+
// Each path in the list is a unique derivation of the conformance in terms of
184+
// other conformance rules.
182185
llvm::MapVector<unsigned, std::vector<SmallVector<unsigned, 2>>> ConformancePaths;
183186

184-
// The set of conformance rules which are protocol refinements, that is rules of
185-
// the form [P].[Q] => [P].
187+
// The set of conformance rules (from all minimization domains) which are protocol
188+
// refinements, that is rules of the form [P].[Q] => [P].
186189
llvm::DenseSet<unsigned> ProtocolRefinements;
187190

188-
// This is the result.
191+
// This is the computed result set of redundant conformance rules in the current
192+
// minimization domain.
189193
llvm::DenseSet<unsigned> &RedundantConformances;
190194

191195
void decomposeTermIntoConformanceRuleLeftHandSides(
@@ -391,17 +395,15 @@ void MinimalConformances::collectConformanceRules() {
391395
if (!rule.isAnyConformanceRule())
392396
continue;
393397

398+
// Save protocol refinement relations in a side table.
399+
if (rule.isProtocolRefinementRule())
400+
ProtocolRefinements.insert(ruleID);
401+
394402
if (!System.isInMinimizationDomain(rule.getLHS().getRootProtocol()))
395403
continue;
396404

397405
ConformanceRules.push_back(ruleID);
398406

399-
// Save protocol refinement relations in a side table.
400-
if (rule.isProtocolRefinementRule()) {
401-
ProtocolRefinements.insert(ruleID);
402-
continue;
403-
}
404-
405407
auto lhs = rule.getLHS();
406408

407409
// Record a parent path if the subject type itself requires a non-trivial
@@ -698,7 +700,7 @@ bool MinimalConformances::isValidConformancePath(
698700
bool MinimalConformances::isValidRefinementPath(
699701
const llvm::SmallVectorImpl<unsigned> &path) const {
700702
for (unsigned ruleID : path) {
701-
if (!System.getRule(ruleID).isProtocolRefinementRule())
703+
if (ProtocolRefinements.count(ruleID) == 0)
702704
return false;
703705
}
704706

@@ -867,8 +869,14 @@ void MinimalConformances::computeMinimalConformances() {
867869
for (const auto &path : paths) {
868870
// Only consider a protocol refinement rule to be redundant if it is
869871
// witnessed by a composition of other protocol refinement rules.
870-
if (isProtocolRefinement && !isValidRefinementPath(path))
872+
if (isProtocolRefinement && !isValidRefinementPath(path)) {
873+
if (Debug.contains(DebugFlags::MinimalConformances)) {
874+
llvm::dbgs() << "Not a refinement path: ";
875+
dumpConformancePath(llvm::errs(), path);
876+
llvm::dbgs() << "\n";
877+
}
871878
continue;
879+
}
872880

873881
llvm::SmallDenseSet<unsigned, 4> visited;
874882
visited.insert(ruleID);

0 commit comments

Comments
 (0)