@@ -535,27 +535,48 @@ ProtocolConformance::getAssociatedConformance(Type assocType,
535
535
ProtocolConformanceRef
536
536
NormalProtocolConformance::getAssociatedConformance (Type assocType,
537
537
ProtocolDecl *protocol) const {
538
+ if (Loader)
539
+ resolveLazyInfo ();
540
+
538
541
assert (assocType->isTypeParameter () &&
539
542
" associated type must be a type parameter" );
540
543
541
544
llvm::Optional<ProtocolConformanceRef> result;
542
545
546
+ auto &ctx = getDeclContext ()->getASTContext ();
547
+
543
548
forEachAssociatedConformance (
544
549
[&](Type t, ProtocolDecl *p, unsigned index) {
545
550
if (t->isEqual (assocType) && p == protocol) {
546
- // Fill in the signature conformances, if we haven't done so yet.
547
- if (!hasComputedAssociatedConformances ()) {
548
- const_cast <NormalProtocolConformance *>(this )
549
- ->finishSignatureConformances ();
551
+ if (!ctx.LangOpts .hasFeature (Feature::TypeWitnessSystemInference)) {
552
+ // Fill in the signature conformances, if we haven't done so yet.
553
+ if (!hasComputedAssociatedConformances ()) {
554
+ const_cast <NormalProtocolConformance *>(this )
555
+ ->finishSignatureConformances ();
556
+ }
557
+ }
558
+
559
+ // Not strictly necessary, but avoids a bit of request evaluator
560
+ // overhead in the happy case.
561
+ if (hasComputedAssociatedConformances ()) {
562
+ result = AssociatedConformances[index];
563
+ if (result)
564
+ return true ;
550
565
}
551
566
552
- result = getAssociatedConformance (index);
567
+ result = evaluateOrDefault (ctx.evaluator ,
568
+ AssociatedConformanceRequest{
569
+ const_cast <NormalProtocolConformance *>(this ),
570
+ t->getCanonicalType (), p, index
571
+ }, ProtocolConformanceRef::forInvalid ());
553
572
return true ;
554
573
}
555
574
556
575
return false ;
557
576
});
558
577
578
+ assert (result && " Subject type must be exactly equal to left-hand side of a"
579
+ " conformance requirement in protocol requirement signature" );
559
580
return *result;
560
581
}
561
582
0 commit comments