@@ -288,7 +288,8 @@ RewriteContext::getProtocolComponentImpl(const ProtocolDecl *proto) {
288
288
// /
289
289
// / This can only be called once, to prevent multiple requirement machines
290
290
// / for being built with the same component.
291
- ArrayRef<const ProtocolDecl *> RewriteContext::getProtocolComponent (
291
+ ArrayRef<const ProtocolDecl *>
292
+ RewriteContext::startComputingRequirementSignatures (
292
293
const ProtocolDecl *proto) {
293
294
auto &component = getProtocolComponentImpl (proto);
294
295
@@ -305,6 +306,17 @@ ArrayRef<const ProtocolDecl *> RewriteContext::getProtocolComponent(
305
306
return component.Protos ;
306
307
}
307
308
309
+ // / Mark the component as having completed, which will ensure that
310
+ // / isRecursivelyComputingRequirementMachine() returns false.
311
+ void RewriteContext::finishComputingRequirementSignatures (
312
+ const ProtocolDecl *proto) {
313
+ auto &component = getProtocolComponentImpl (proto);
314
+
315
+ assert (component.ComputingRequirementSignatures &&
316
+ " Didn't call startComputingRequirementSignatures()" );
317
+ component.ComputedRequirementSignatures = true ;
318
+ }
319
+
308
320
// / Get the list of protocols in the strongly connected component (SCC)
309
321
// / of the protocol dependency graph containing the given protocol.
310
322
// /
@@ -340,11 +352,12 @@ RequirementMachine *RewriteContext::getRequirementMachine(
340
352
return newMachine;
341
353
}
342
354
355
+ // / Note: This doesn't use Evaluator::hasActiveRequest(), because in reality
356
+ // / the active request could be for any protocol in the connected component.
357
+ // /
358
+ // / Instead, just check a flag set in the component itself.
343
359
bool RewriteContext::isRecursivelyConstructingRequirementMachine (
344
360
const ProtocolDecl *proto) {
345
- if (proto->isRequirementSignatureComputed ())
346
- return false ;
347
-
348
361
auto found = Protos.find (proto);
349
362
if (found == Protos.end ())
350
363
return false ;
@@ -353,7 +366,10 @@ bool RewriteContext::isRecursivelyConstructingRequirementMachine(
353
366
if (component == Components.end ())
354
367
return false ;
355
368
356
- return component->second .ComputingRequirementSignatures ;
369
+ // If we've started but not finished, we're in the middle of computing
370
+ // requirement signatures.
371
+ return (component->second .ComputingRequirementSignatures &&
372
+ !component->second .ComputedRequirementSignatures );
357
373
}
358
374
359
375
// / We print stats in the destructor, which should get executed at the end of
0 commit comments