@@ -388,34 +388,6 @@ ConditionalRequirementsRequest::evaluate(Evaluator &evaluator,
388
388
return NPC->getProtocol ()->getASTContext ().AllocateCopy (unsatReqs);
389
389
}
390
390
391
- void NormalProtocolConformance::setSignatureConformances (
392
- ArrayRef<ProtocolConformanceRef> conformances) {
393
- if (conformances.empty ()) {
394
- SignatureConformances = { };
395
- return ;
396
- }
397
-
398
- auto &ctx = getProtocol ()->getASTContext ();
399
- SignatureConformances = ctx.AllocateCopy (conformances);
400
-
401
- #if !NDEBUG
402
- unsigned idx = 0 ;
403
- auto reqs = getProtocol ()->getRequirementSignature ().getRequirements ();
404
- for (const auto &req : reqs) {
405
- if (req.getKind () == RequirementKind::Conformance) {
406
- assert (!conformances[idx].isConcrete () ||
407
- !conformances[idx].getConcrete ()->getType ()->hasArchetype () &&
408
- " Should have interface types here" );
409
- assert (idx < conformances.size ());
410
- assert (conformances[idx].isInvalid () ||
411
- conformances[idx].getRequirement () == req.getProtocolDecl ());
412
- ++idx;
413
- }
414
- }
415
- assert (idx == conformances.size () && " Too many conformances" );
416
- #endif
417
- }
418
-
419
391
void NormalProtocolConformance::resolveLazyInfo () const {
420
392
assert (Loader);
421
393
@@ -552,14 +524,12 @@ NormalProtocolConformance::getAssociatedConformance(Type assocType,
552
524
[&](Type t, ProtocolDecl *p, unsigned index) {
553
525
if (t->isEqual (assocType) && p == protocol) {
554
526
// Fill in the signature conformances, if we haven't done so yet.
555
- if (getSignatureConformances ().empty ()) {
556
- const_cast <NormalProtocolConformance *>(this )->finishSignatureConformances ();
527
+ if (!hasComputedAssociatedConformances ()) {
528
+ const_cast <NormalProtocolConformance *>(this )
529
+ ->finishSignatureConformances ();
557
530
}
558
531
559
- assert (!getSignatureConformances ().empty () &&
560
- " signature conformances not yet computed" );
561
-
562
- result = getSignatureConformances ()[index];
532
+ result = getAssociatedConformance (index);
563
533
return true ;
564
534
}
565
535
@@ -639,55 +609,53 @@ recursivelySubstituteBaseType(ModuleDecl *module,
639
609
640
610
// / Collect conformances for the requirement signature.
641
611
void NormalProtocolConformance::finishSignatureConformances () {
642
- if (!SignatureConformances. empty () )
643
- return ;
612
+ if (Loader )
613
+ resolveLazyInfo () ;
644
614
645
- auto *proto = getProtocol ();
646
- auto reqSig = proto->getRequirementSignature ().getRequirements ();
647
- if (reqSig.empty ())
615
+ if (hasComputedAssociatedConformances ())
648
616
return ;
649
617
650
- SmallVector<ProtocolConformanceRef, 4 > reqConformances;
651
- for (const auto &req : reqSig) {
652
- if (req.getKind () != RequirementKind::Conformance)
653
- continue ;
618
+ createAssociatedConformanceArray ();
654
619
655
- ModuleDecl *module = getDeclContext ()->getParentModule ();
620
+ auto *proto = getProtocol ();
621
+ ModuleDecl *module = getDeclContext ()->getParentModule ();
656
622
657
- Type substTy;
658
- auto origTy = req.getFirstType ();
659
- if (origTy->isEqual (proto->getSelfInterfaceType ())) {
660
- substTy = getType ();
661
- } else {
662
- auto *depMemTy = origTy->castTo <DependentMemberType>();
663
- substTy = recursivelySubstituteBaseType (module , this , depMemTy);
664
- }
665
- auto reqProto = req.getProtocolDecl ();
623
+ forEachAssociatedConformance (
624
+ [&](Type origTy, ProtocolDecl *reqProto, unsigned index) {
625
+ Type substTy;
626
+
627
+ if (origTy->isEqual (proto->getSelfInterfaceType ())) {
628
+ substTy = getType ();
629
+ } else {
630
+ auto *depMemTy = origTy->castTo <DependentMemberType>();
631
+ substTy = recursivelySubstituteBaseType (module , this , depMemTy);
632
+ }
666
633
667
- // Looking up a conformance for a contextual type and mapping the
668
- // conformance context produces a more accurate result than looking
669
- // up a conformance from an interface type.
670
- //
671
- // This can happen if the conformance has an associated conformance
672
- // depending on an associated type that is made concrete in a
673
- // refining protocol.
674
- //
675
- // That is, the conformance of an interface type G<T> : P really
676
- // depends on the generic signature of the current context, because
677
- // performing the lookup in a "more" constrained extension than the
678
- // one where the conformance was defined must produce concrete
679
- // conformances.
680
- //
681
- // FIXME: Eliminate this, perhaps by adding a variant of
682
- // lookupConformance() taking a generic signature.
683
- if (substTy->hasTypeParameter ())
684
- substTy = getDeclContext ()->mapTypeIntoContext (substTy);
685
-
686
- reqConformances.push_back (module ->lookupConformance (substTy, reqProto,
687
- /* allowMissing=*/ true )
688
- .mapConformanceOutOfContext ());
689
- }
690
- setSignatureConformances (reqConformances);
634
+ // Looking up a conformance for a contextual type and mapping the
635
+ // conformance context produces a more accurate result than looking
636
+ // up a conformance from an interface type.
637
+ //
638
+ // This can happen if the conformance has an associated conformance
639
+ // depending on an associated type that is made concrete in a
640
+ // refining protocol.
641
+ //
642
+ // That is, the conformance of an interface type G<T> : P really
643
+ // depends on the generic signature of the current context, because
644
+ // performing the lookup in a "more" constrained extension than the
645
+ // one where the conformance was defined must produce concrete
646
+ // conformances.
647
+ //
648
+ // FIXME: Eliminate this, perhaps by adding a variant of
649
+ // lookupConformance() taking a generic signature.
650
+ if (substTy->hasTypeParameter ())
651
+ substTy = getDeclContext ()->mapTypeIntoContext (substTy);
652
+
653
+ auto assocConf = module ->lookupConformance (substTy, reqProto,
654
+ /* allowMissing=*/ true )
655
+ .mapConformanceOutOfContext ();
656
+ setAssociatedConformance (index, assocConf);
657
+ return false ;
658
+ });
691
659
}
692
660
693
661
Witness RootProtocolConformance::getWitness (ValueDecl *requirement) const {
0 commit comments