@@ -288,7 +288,8 @@ RewriteContext::getProtocolComponentImpl(const ProtocolDecl *proto) {
288288// /
289289// / This can only be called once, to prevent multiple requirement machines
290290// / for being built with the same component.
291- ArrayRef<const ProtocolDecl *> RewriteContext::getProtocolComponent (
291+ ArrayRef<const ProtocolDecl *>
292+ RewriteContext::startComputingRequirementSignatures (
292293 const ProtocolDecl *proto) {
293294 auto &component = getProtocolComponentImpl (proto);
294295
@@ -305,6 +306,17 @@ ArrayRef<const ProtocolDecl *> RewriteContext::getProtocolComponent(
305306 return component.Protos ;
306307}
307308
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+
308320// / Get the list of protocols in the strongly connected component (SCC)
309321// / of the protocol dependency graph containing the given protocol.
310322// /
@@ -340,11 +352,12 @@ RequirementMachine *RewriteContext::getRequirementMachine(
340352 return newMachine;
341353}
342354
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.
343359bool RewriteContext::isRecursivelyConstructingRequirementMachine (
344360 const ProtocolDecl *proto) {
345- if (proto->isRequirementSignatureComputed ())
346- return false ;
347-
348361 auto found = Protos.find (proto);
349362 if (found == Protos.end ())
350363 return false ;
@@ -353,7 +366,10 @@ bool RewriteContext::isRecursivelyConstructingRequirementMachine(
353366 if (component == Components.end ())
354367 return false ;
355368
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 );
357373}
358374
359375// / We print stats in the destructor, which should get executed at the end of
0 commit comments