Skip to content

Commit e0a3344

Browse files
committed
RequirementMachine: Fold what remains of ProtocolGraph into RewriteSystemBuilder
1 parent caea460 commit e0a3344

File tree

5 files changed

+47
-154
lines changed

5 files changed

+47
-154
lines changed

lib/AST/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ add_swift_host_library(swiftAST STATIC
7979
RequirementMachine/GenericSignatureQueries.cpp
8080
RequirementMachine/PropertyMap.cpp
8181
RequirementMachine/PropertyUnification.cpp
82-
RequirementMachine/ProtocolGraph.cpp
8382
RequirementMachine/RequirementMachine.cpp
8483
RequirementMachine/RequirementMachineRequests.cpp
8584
RequirementMachine/RewriteContext.cpp

lib/AST/RequirementMachine/ProtocolGraph.cpp

Lines changed: 0 additions & 66 deletions
This file was deleted.

lib/AST/RequirementMachine/ProtocolGraph.h

Lines changed: 0 additions & 79 deletions
This file was deleted.

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,23 @@ struct RewriteSystemBuilder {
3232
RewriteContext &Context;
3333
bool Dump;
3434

35-
ProtocolGraph Protocols;
35+
/// The keys are the unique protocols we've added so far. The value indicates
36+
/// whether the protocol's SCC is an initial component for the rewrite system.
37+
///
38+
/// A rewrite system built from a generic signature does not have any initial
39+
/// protocols.
40+
///
41+
/// A rewrite system built from a protocol SCC has the protocols of the SCC
42+
/// itself as initial protocols.
43+
///
44+
/// If a protocol is an initial protocol, we use its structural requirements
45+
/// instead of its requirement signature as the basis of its rewrite rules.
46+
///
47+
/// This is what breaks the cycle in requirement signature computation for a
48+
/// group of interdependent protocols.
49+
llvm::DenseMap<const ProtocolDecl *, bool> ProtocolMap;
50+
std::vector<const ProtocolDecl *> Protocols;
51+
3652
std::vector<std::pair<MutableTerm, MutableTerm>> AssociatedTypeRules;
3753
std::vector<std::pair<MutableTerm, MutableTerm>> RequirementRules;
3854

@@ -44,6 +60,8 @@ struct RewriteSystemBuilder {
4460
: Context(ctx), Dump(dump) {}
4561
void addGenericSignature(CanGenericSignature sig);
4662
void addProtocols(ArrayRef<const ProtocolDecl *> proto);
63+
void addProtocol(const ProtocolDecl *proto,
64+
bool initialComponent);
4765
void addAssociatedType(const AssociatedTypeDecl *type,
4866
const ProtocolDecl *proto);
4967
void addRequirement(const Requirement &req,
@@ -84,8 +102,11 @@ RewriteSystemBuilder::getConcreteSubstitutionSchema(CanType concreteType,
84102
void RewriteSystemBuilder::addGenericSignature(CanGenericSignature sig) {
85103
// Collect all protocols transitively referenced from the generic signature's
86104
// requirements.
87-
Protocols.visitRequirements(sig.getRequirements());
88-
Protocols.compute();
105+
for (auto req : sig.getRequirements()) {
106+
if (req.getKind() == RequirementKind::Conformance) {
107+
addProtocol(req.getProtocolDecl(), /*initialComponent=*/false);
108+
}
109+
}
89110

90111
processProtocolDependencies();
91112

@@ -97,8 +118,9 @@ void RewriteSystemBuilder::addGenericSignature(CanGenericSignature sig) {
97118
void RewriteSystemBuilder::addProtocols(ArrayRef<const ProtocolDecl *> protos) {
98119
// Collect all protocols transitively referenced from this connected component
99120
// of the protocol dependency graph.
100-
Protocols.visitProtocols(protos);
101-
Protocols.compute();
121+
for (auto proto : protos) {
122+
addProtocol(proto, /*initialComponent=*/true);
123+
}
102124

103125
processProtocolDependencies();
104126
}
@@ -228,9 +250,27 @@ void RewriteSystemBuilder::addRequirement(const Requirement &req,
228250
RequirementRules.emplace_back(subjectTerm, constraintTerm);
229251
}
230252

253+
/// Record information about a protocol if we have no seen it yet.
254+
void RewriteSystemBuilder::addProtocol(const ProtocolDecl *proto,
255+
bool initialComponent) {
256+
if (ProtocolMap.count(proto) > 0)
257+
return;
258+
259+
ProtocolMap[proto] = initialComponent;
260+
Protocols.push_back(proto);
261+
}
262+
231263
void RewriteSystemBuilder::processProtocolDependencies() {
264+
unsigned i = 0;
265+
while (i < Protocols.size()) {
266+
auto *proto = Protocols[i++];
267+
for (auto *depProto : proto->getProtocolDependencies()) {
268+
addProtocol(depProto, /*initialComponent=*/false);
269+
}
270+
}
271+
232272
// Add rewrite rules for each protocol.
233-
for (auto *proto : Protocols.getProtocols()) {
273+
for (auto *proto : Protocols) {
234274
if (Dump) {
235275
llvm::dbgs() << "protocol " << proto->getName() << " {\n";
236276
}
@@ -250,7 +290,7 @@ void RewriteSystemBuilder::processProtocolDependencies() {
250290
// Otherwise, we should either already have a requirement signature, or
251291
// we can trigger the computation of the requirement signatures of the
252292
// next component recursively.
253-
if (Protocols.getProtocolInfo(proto).InitialComponent) {
293+
if (ProtocolMap[proto]) {
254294
for (auto req : proto->getStructuralRequirements())
255295
addRequirement(req.req.getCanonical(), proto);
256296
} else {

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <vector>
1919

2020
#include "PropertyMap.h"
21-
#include "ProtocolGraph.h"
2221
#include "RewriteContext.h"
2322
#include "RewriteSystem.h"
2423

0 commit comments

Comments
 (0)