@@ -275,7 +275,19 @@ static bool shouldSplitConcreteEquivalenceClasses(GenericSignature sig) {
275
275
static void splitConcreteEquivalenceClasses (
276
276
ASTContext &ctx,
277
277
GenericSignature sig,
278
- SmallVectorImpl<StructuralRequirement> &requirements) {
278
+ SmallVectorImpl<StructuralRequirement> &requirements,
279
+ unsigned &attempt) {
280
+ unsigned maxAttempts =
281
+ ctx.LangOpts .RequirementMachineMaxSplitConcreteEquivClassAttempts ;
282
+
283
+ ++attempt;
284
+ if (attempt >= maxAttempts) {
285
+ llvm::errs () << " Splitting concrete equivalence classes did not "
286
+ << " reach fixed point after " << attempt << " attempts.\n " ;
287
+ llvm::errs () << " Last result: " << sig << " \n " ;
288
+ abort ();
289
+ }
290
+
279
291
requirements.clear ();
280
292
281
293
for (auto req : sig.getRequirements ()) {
@@ -428,6 +440,7 @@ AbstractGenericSignatureRequestRQM::evaluate(
428
440
}
429
441
}
430
442
443
+ unsigned attempt = 0 ;
431
444
for (;;) {
432
445
// Heap-allocate the requirement machine to save stack space.
433
446
std::unique_ptr<RequirementMachine> machine (new RequirementMachine (
@@ -448,7 +461,7 @@ AbstractGenericSignatureRequestRQM::evaluate(
448
461
449
462
if (!errorFlags) {
450
463
if (shouldSplitConcreteEquivalenceClasses (result)) {
451
- splitConcreteEquivalenceClasses (ctx, result, requirements);
464
+ splitConcreteEquivalenceClasses (ctx, result, requirements, attempt );
452
465
continue ;
453
466
}
454
467
@@ -568,6 +581,7 @@ InferredGenericSignatureRequestRQM::evaluate(
568
581
}
569
582
}
570
583
584
+ unsigned attempt = 0 ;
571
585
for (;;) {
572
586
// Heap-allocate the requirement machine to save stack space.
573
587
std::unique_ptr<RequirementMachine> machine (new RequirementMachine (
@@ -599,7 +613,8 @@ InferredGenericSignatureRequestRQM::evaluate(
599
613
auto result = GenericSignature::get (genericParams, minimalRequirements);
600
614
auto errorFlags = machine->getErrors ();
601
615
602
- if (ctx.LangOpts .RequirementMachineInferredSignatures ==
616
+ if (attempt == 0 &&
617
+ ctx.LangOpts .RequirementMachineInferredSignatures ==
603
618
RequirementMachineMode::Enabled) {
604
619
machine->System .computeRedundantRequirementDiagnostics (errors);
605
620
diagnoseRequirementErrors (ctx, errors, allowConcreteGenericParams);
@@ -608,8 +623,9 @@ InferredGenericSignatureRequestRQM::evaluate(
608
623
// FIXME: Handle allowConcreteGenericParams
609
624
610
625
if (!errorFlags) {
626
+ // Check if we need to rebuild the signature.
611
627
if (shouldSplitConcreteEquivalenceClasses (result)) {
612
- splitConcreteEquivalenceClasses (ctx, result, requirements);
628
+ splitConcreteEquivalenceClasses (ctx, result, requirements, attempt );
613
629
continue ;
614
630
}
615
631
0 commit comments