34
34
#include < deque>
35
35
#include < vector>
36
36
37
+ #include " RewriteContext.h"
37
38
#include " RewriteSystem.h"
38
39
39
40
using namespace swift ;
@@ -72,12 +73,23 @@ Symbol Symbol::prependPrefixToConcreteSubstitutions(
72
73
// / - If P inherits from Q, this is just [P:T].
73
74
// / - If Q inherits from P, this is just [Q:T].
74
75
// / - If P and Q are unrelated, this is [P&Q:T].
75
- Symbol RewriteSystem::mergeAssociatedTypes (Symbol lhs, Symbol rhs) const {
76
+ // /
77
+ // / Note that the protocol graph is not part of the caching key; each
78
+ // / protocol graph is a subgraph of the global inheritance graph, so
79
+ // / the specific choice of subgraph does not change the result.
80
+ Symbol RewriteContext::mergeAssociatedTypes (Symbol lhs, Symbol rhs,
81
+ const ProtocolGraph &graph) {
82
+ auto key = std::make_pair (lhs, rhs);
83
+
84
+ auto found = MergedAssocTypes.find (key);
85
+ if (found != MergedAssocTypes.end ())
86
+ return found->second ;
87
+
76
88
// Check preconditions that were established by RewriteSystem::addRule().
77
89
assert (lhs.getKind () == Symbol::Kind::AssociatedType);
78
90
assert (rhs.getKind () == Symbol::Kind::AssociatedType);
79
91
assert (lhs.getName () == rhs.getName ());
80
- assert (lhs.compare (rhs, Protos ) > 0 );
92
+ assert (lhs.compare (rhs, graph ) > 0 );
81
93
82
94
auto protos = lhs.getProtocols ();
83
95
auto otherProtos = rhs.getProtocols ();
@@ -92,7 +104,7 @@ Symbol RewriteSystem::mergeAssociatedTypes(Symbol lhs, Symbol rhs) const {
92
104
std::back_inserter (newProtos),
93
105
[&](const ProtocolDecl *lhs,
94
106
const ProtocolDecl *rhs) -> int {
95
- return Protos .compareProtocols (lhs, rhs) < 0 ;
107
+ return graph .compareProtocols (lhs, rhs) < 0 ;
96
108
});
97
109
98
110
// Prune duplicates and protocols that are inherited by other
@@ -101,7 +113,7 @@ Symbol RewriteSystem::mergeAssociatedTypes(Symbol lhs, Symbol rhs) const {
101
113
for (const auto *newProto : newProtos) {
102
114
auto inheritsFrom = [&](const ProtocolDecl *thisProto) {
103
115
return (thisProto == newProto ||
104
- Protos .inheritsFrom (thisProto, newProto));
116
+ graph .inheritsFrom (thisProto, newProto));
105
117
};
106
118
107
119
if (std::find_if (minimalProtos.begin (), minimalProtos.end (),
@@ -120,7 +132,12 @@ Symbol RewriteSystem::mergeAssociatedTypes(Symbol lhs, Symbol rhs) const {
120
132
// of the two sets.
121
133
assert (minimalProtos.size () <= protos.size () + otherProtos.size ());
122
134
123
- return Symbol::forAssociatedType (minimalProtos, lhs.getName (), Context);
135
+ auto result = Symbol::forAssociatedType (minimalProtos, lhs.getName (), *this );
136
+ auto inserted = MergedAssocTypes.insert (std::make_pair (key, result));
137
+ assert (inserted.second );
138
+ (void ) inserted;
139
+
140
+ return result;
124
141
}
125
142
126
143
// / Consider the following example:
@@ -207,7 +224,8 @@ void RewriteSystem::processMergedAssociatedTypes() {
207
224
llvm::dbgs () << lhs << " => " << rhs << " \n " ;
208
225
}
209
226
210
- auto mergedSymbol = mergeAssociatedTypes (lhs.back (), rhs.back ());
227
+ auto mergedSymbol = Context.mergeAssociatedTypes (lhs.back (), rhs.back (),
228
+ Protos);
211
229
if (DebugMerge) {
212
230
llvm::dbgs () << " ### Merged symbol " << mergedSymbol << " \n " ;
213
231
}
0 commit comments