@@ -288,7 +288,8 @@ RequirementSignatureRequestRQM::evaluate(Evaluator &evaluator,
288288
289289 auto minimalRequirements = machine->computeMinimalProtocolRequirements ();
290290
291- if (!machine->getErrors ()) {
291+ if (!machine->getErrors ().contains (
292+ GenericSignatureErrorFlags::HasInvalidRequirements)) {
292293 if (shouldSplitConcreteEquivalenceClasses (minimalRequirements, machine.get ())) {
293294 ++attempt;
294295 splitConcreteEquivalenceClasses (ctx, minimalRequirements,
@@ -345,15 +346,20 @@ RequirementSignatureRequestRQM::evaluate(Evaluator &evaluator,
345346 /* allowConcreteGenericParams=*/ false );
346347 }
347348
349+ if (!machine->getErrors ())
350+ rewriteCtx.installRequirementMachine (proto, std::move (machine));
351+
348352 // Return the result for the specific protocol this request was kicked off on.
349353 return *result;
350354 }
351355}
352356
353357// / Builds the top-level generic signature requirements for this rewrite system.
354- std::vector<Requirement>
355- RequirementMachine::computeMinimalGenericSignatureRequirements (
358+ GenericSignature
359+ RequirementMachine::computeMinimalGenericSignature (
356360 bool reconstituteSugar) {
361+ assert (!Sig &&
362+ " Already computed minimal generic signature" );
357363 assert (System.getProtocols ().empty () &&
358364 " Not a top-level generic signature rewrite system" );
359365 assert (!Params.empty () &&
@@ -375,7 +381,14 @@ RequirementMachine::computeMinimalGenericSignatureRequirements(
375381 reconstituteSugar, reqs, aliases);
376382 assert (aliases.empty ());
377383
378- return reqs;
384+ auto sig = GenericSignature::get (getGenericParams (), reqs);
385+
386+ // Remember the signature for generic signature queries. In particular,
387+ // getConformanceAccessPath() needs the current requirement machine's
388+ // generic signature.
389+ Sig = sig.getCanonicalSignature ();
390+
391+ return sig;
379392}
380393
381394// / Check whether the inputs to the \c AbstractGenericSignatureRequest are
@@ -549,14 +562,11 @@ AbstractGenericSignatureRequestRQM::evaluate(
549562
550563 // We pass reconstituteSugar=false to ensure that if the original
551564 // requirements were canonical, the final signature remains canonical.
552- auto minimalRequirements =
553- machine->computeMinimalGenericSignatureRequirements (
565+ auto result = machine->computeMinimalGenericSignature (
554566 /* reconstituteSugar=*/ false );
555-
556- auto result = GenericSignature::get (genericParams, minimalRequirements);
557567 auto errorFlags = machine->getErrors ();
558568
559- if (!errorFlags) {
569+ if (!errorFlags. contains (GenericSignatureErrorFlags::HasInvalidRequirements) ) {
560570 if (shouldSplitConcreteEquivalenceClasses (result.getRequirements (),
561571 /* proto=*/ nullptr ,
562572 machine.get ())) {
@@ -567,7 +577,19 @@ AbstractGenericSignatureRequestRQM::evaluate(
567577 requirements, attempt);
568578 continue ;
569579 }
580+ }
570581
582+ if (!errorFlags) {
583+ // If this signature was minimized without errors or non-redundant
584+ // concrete conformances, we can re-use the requirement machine for
585+ // subsequent queries, instead of building a new requirement machine
586+ // from the minimized signature. Do this before verify(), which
587+ // performs queries.
588+ rewriteCtx.installRequirementMachine (result.getCanonicalSignature (),
589+ std::move (machine));
590+ }
591+
592+ if (!errorFlags.contains (GenericSignatureErrorFlags::HasInvalidRequirements)) {
571593 // Check invariants.
572594 result.verify ();
573595 }
@@ -731,11 +753,8 @@ InferredGenericSignatureRequestRQM::evaluate(
731753 result, GenericSignatureErrorFlags::CompletionFailed);
732754 }
733755
734- auto minimalRequirements =
735- machine->computeMinimalGenericSignatureRequirements (
756+ auto result = machine->computeMinimalGenericSignature (
736757 /* reconstituteSugar=*/ true );
737-
738- auto result = GenericSignature::get (genericParams, minimalRequirements);
739758 auto errorFlags = machine->getErrors ();
740759
741760 if (attempt == 0 &&
@@ -747,7 +766,7 @@ InferredGenericSignatureRequestRQM::evaluate(
747766
748767 // FIXME: Handle allowConcreteGenericParams
749768
750- if (!errorFlags) {
769+ if (!errorFlags. contains (GenericSignatureErrorFlags::HasInvalidRequirements) ) {
751770 // Check if we need to rebuild the signature.
752771 if (shouldSplitConcreteEquivalenceClasses (result.getRequirements (),
753772 /* proto=*/ nullptr ,
@@ -759,7 +778,19 @@ InferredGenericSignatureRequestRQM::evaluate(
759778 requirements, attempt);
760779 continue ;
761780 }
781+ }
782+
783+ if (!errorFlags) {
784+ // If this signature was minimized without errors or non-redundant
785+ // concrete conformances, we can re-use the requirement machine for
786+ // subsequent queries, instead of building a new requirement machine
787+ // from the minimized signature. Do this before verify(), which
788+ // performs queries.
789+ rewriteCtx.installRequirementMachine (result.getCanonicalSignature (),
790+ std::move (machine));
791+ }
762792
793+ if (!errorFlags.contains (GenericSignatureErrorFlags::HasInvalidRequirements)) {
763794 // Check invariants.
764795 result.verify ();
765796 }
0 commit comments