@@ -35,12 +35,32 @@ RequirementMachine::RequirementMachine(RewriteContext &ctx)
35
35
36
36
RequirementMachine::~RequirementMachine () {}
37
37
38
+ static void checkCompletionResult (const RequirementMachine &machine,
39
+ CompletionResult result) {
40
+ switch (result) {
41
+ case CompletionResult::Success:
42
+ break ;
43
+
44
+ case CompletionResult::MaxIterations:
45
+ llvm::errs () << " Rewrite system exceeds maximum completion step count\n " ;
46
+ machine.dump (llvm::errs ());
47
+ abort ();
48
+
49
+ case CompletionResult::MaxDepth:
50
+ llvm::errs () << " Rewrite system exceeds maximum completion depth\n " ;
51
+ machine.dump (llvm::errs ());
52
+ abort ();
53
+ }
54
+ }
55
+
38
56
// / Build a requirement machine for the requirements of a generic signature.
39
57
// /
40
58
// / This must only be called exactly once, before any other operations are
41
59
// / performed on this requirement machine.
42
60
// /
43
61
// / Used by ASTContext::getOrCreateRequirementMachine().
62
+ // /
63
+ // / Asserts if completion fails within the configured number of steps.
44
64
void RequirementMachine::initWithGenericSignature (CanGenericSignature sig) {
45
65
Sig = sig;
46
66
Params.append (sig.getGenericParams ().begin (),
@@ -64,7 +84,8 @@ void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
64
84
std::move (builder.PermanentRules ),
65
85
std::move (builder.RequirementRules ));
66
86
67
- computeCompletion (RewriteSystem::DisallowInvalidRequirements);
87
+ auto result = computeCompletion (RewriteSystem::DisallowInvalidRequirements);
88
+ checkCompletionResult (*this , result);
68
89
69
90
if (Dump) {
70
91
llvm::dbgs () << " }\n " ;
@@ -79,7 +100,10 @@ void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
79
100
// / performed on this requirement machine.
80
101
// /
81
102
// / Used by RequirementSignatureRequest.
82
- void RequirementMachine::initWithProtocols (ArrayRef<const ProtocolDecl *> protos) {
103
+ // /
104
+ // / Returns failure if completion fails within the configured number of steps.
105
+ CompletionResult
106
+ RequirementMachine::initWithProtocols (ArrayRef<const ProtocolDecl *> protos) {
83
107
Protos = protos;
84
108
85
109
FrontendStatsTracer tracer (Stats, " build-rewrite-system" );
@@ -100,12 +124,13 @@ void RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos
100
124
std::move (builder.PermanentRules ),
101
125
std::move (builder.RequirementRules ));
102
126
103
- // FIXME: Only if the protocols were written in source, though.
104
- computeCompletion (RewriteSystem::AllowInvalidRequirements);
127
+ auto result = computeCompletion (RewriteSystem::AllowInvalidRequirements);
105
128
106
129
if (Dump) {
107
130
llvm::dbgs () << " }\n " ;
108
131
}
132
+
133
+ return result;
109
134
}
110
135
111
136
// / Build a requirement machine from a set of generic parameters and
@@ -115,6 +140,8 @@ void RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos
115
140
// / performed on this requirement machine.
116
141
// /
117
142
// / Used by AbstractGenericSignatureRequest.
143
+ // /
144
+ // / Asserts if completion fails within the configured number of steps.
118
145
void RequirementMachine::initWithAbstractRequirements (
119
146
ArrayRef<GenericTypeParamType *> genericParams,
120
147
ArrayRef<Requirement> requirements) {
@@ -139,7 +166,8 @@ void RequirementMachine::initWithAbstractRequirements(
139
166
std::move (builder.PermanentRules ),
140
167
std::move (builder.RequirementRules ));
141
168
142
- computeCompletion (RewriteSystem::AllowInvalidRequirements);
169
+ auto result = computeCompletion (RewriteSystem::AllowInvalidRequirements);
170
+ checkCompletionResult (*this , result);
143
171
144
172
if (Dump) {
145
173
llvm::dbgs () << " }\n " ;
@@ -153,7 +181,10 @@ void RequirementMachine::initWithAbstractRequirements(
153
181
// / performed on this requirement machine.
154
182
// /
155
183
// / Used by InferredGenericSignatureRequest.
156
- void RequirementMachine::initWithWrittenRequirements (
184
+ // /
185
+ // / Returns failure if completion fails within the configured number of steps.
186
+ CompletionResult
187
+ RequirementMachine::initWithWrittenRequirements (
157
188
ArrayRef<GenericTypeParamType *> genericParams,
158
189
ArrayRef<StructuralRequirement> requirements) {
159
190
Params.append (genericParams.begin (), genericParams.end ());
@@ -177,17 +208,20 @@ void RequirementMachine::initWithWrittenRequirements(
177
208
std::move (builder.PermanentRules ),
178
209
std::move (builder.RequirementRules ));
179
210
180
- computeCompletion (RewriteSystem::AllowInvalidRequirements);
211
+ auto result = computeCompletion (RewriteSystem::AllowInvalidRequirements);
181
212
182
213
if (Dump) {
183
214
llvm::dbgs () << " }\n " ;
184
215
}
216
+
217
+ return result;
185
218
}
186
219
187
220
// / Attempt to obtain a confluent rewrite system by iterating the Knuth-Bendix
188
221
// / completion procedure together with property map construction until fixed
189
222
// / point.
190
- void RequirementMachine::computeCompletion (RewriteSystem::ValidityPolicy policy) {
223
+ CompletionResult
224
+ RequirementMachine::computeCompletion (RewriteSystem::ValidityPolicy policy) {
191
225
while (true ) {
192
226
// First, run the Knuth-Bendix algorithm to resolve overlapping rules.
193
227
auto result = System.computeConfluentCompletion (
@@ -200,26 +234,8 @@ void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy)
200
234
}
201
235
202
236
// Check for failure.
203
- auto checkCompletionResult = [&]() {
204
- switch (result.first ) {
205
- case CompletionResult::Success:
206
- break ;
207
-
208
- case CompletionResult::MaxIterations:
209
- llvm::errs () << " Generic signature " << Sig
210
- << " exceeds maximum completion step count\n " ;
211
- System.dump (llvm::errs ());
212
- abort ();
213
-
214
- case CompletionResult::MaxDepth:
215
- llvm::errs () << " Generic signature " << Sig
216
- << " exceeds maximum completion depth\n " ;
217
- System.dump (llvm::errs ());
218
- abort ();
219
- }
220
- };
221
-
222
- checkCompletionResult ();
237
+ if (result.first != CompletionResult::Success)
238
+ return result.first ;
223
239
224
240
// Check invariants.
225
241
System.verifyRewriteRules (policy);
@@ -236,7 +252,9 @@ void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy)
236
252
.NumRequirementMachineUnifiedConcreteTerms += result.second ;
237
253
}
238
254
239
- checkCompletionResult ();
255
+ // Check for failure.
256
+ if (result.first != CompletionResult::Success)
257
+ return result.first ;
240
258
241
259
// If buildPropertyMap() added new rules, we run another round of
242
260
// Knuth-Bendix, and build the property map again.
@@ -250,6 +268,8 @@ void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy)
250
268
251
269
assert (!Complete);
252
270
Complete = true ;
271
+
272
+ return CompletionResult::Success;
253
273
}
254
274
255
275
bool RequirementMachine::isComplete () const {
0 commit comments