@@ -776,9 +776,21 @@ GenericSignatureImpl::getConformanceAccessPath(Type type,
776
776
auto conforms = equivClass->conformsTo .find (protocol);
777
777
assert (conforms != equivClass->conformsTo .end ());
778
778
779
- // Look at every requirement source for this conformance. If all sources are
780
- // explicit, leave these three values empty. Otherwise, they are computed
781
- // from the 'best' derived requirement source for this conformance.
779
+ auto rootType = equivClass->getAnchor (builder, { });
780
+ if (hasConformanceInSignature (getRequirements (), rootType, protocol)) {
781
+ ConformanceAccessPath::Entry root (rootType, protocol);
782
+ ArrayRef<ConformanceAccessPath::Entry> path (root);
783
+
784
+ ConformanceAccessPath result (builder.getASTContext ().AllocateCopy (path));
785
+ equivClass->conformanceAccessPathCache .insert ({protocol, result});
786
+
787
+ return result;
788
+ }
789
+
790
+ // This conformance comes from a derived source.
791
+ //
792
+ // To recover this the conformance, we recursively recover the conformance
793
+ // of the shortest parent type to the parent protocol first.
782
794
Type shortestParentType;
783
795
Type shortestSubjectType;
784
796
ProtocolDecl *shortestParentProto = nullptr ;
@@ -823,28 +835,13 @@ GenericSignatureImpl::getConformanceAccessPath(Type type,
823
835
824
836
case RequirementSource::ProtocolRequirement:
825
837
case RequirementSource::InferredProtocolRequirement: {
826
- if (source->parent ->kind == RequirementSource::RequirementSignatureSelf) {
827
- // This is a top-level requirement in the requirement signature that is
828
- // currently being computed. This is not a derived source, so it
829
- // contributes nothing to the "shortest parent type" computation.
830
- break ;
831
- }
832
-
833
- auto constraintType = constraint.getSubjectDependentType ({ });
834
-
835
- // Skip self-recursive sources.
836
- bool derivedViaConcrete = false ;
837
- if (source->getMinimalConformanceSource (builder, constraintType, protocol,
838
- derivedViaConcrete) != source)
839
- break ;
840
-
838
+ assert (source->parent ->kind != RequirementSource::RequirementSignatureSelf);
841
839
842
840
// If we have a derived conformance requirement like T[.P].X : Q, we can
843
841
// recursively compute the conformance access path for T : P, and append
844
842
// the path element (Self.X : Q).
845
843
auto parentType = source->parent ->getAffectedType ()->getCanonicalType ();
846
844
auto subjectType = source->getStoredType ()->getCanonicalType ();
847
-
848
845
auto *parentProto = source->getProtocolDecl ();
849
846
850
847
// We might have multiple candidate parent types and protocols for the
@@ -861,33 +858,22 @@ GenericSignatureImpl::getConformanceAccessPath(Type type,
861
858
}
862
859
}
863
860
861
+ assert (shortestParentType);
862
+
864
863
SmallVector<ConformanceAccessPath::Entry, 2 > path;
865
864
866
- if (!shortestParentType) {
867
- // All requirement sources were explicit. This means we can recover the
868
- // conformance directly from the generic signature; canonicalize the
869
- // dependent type and add it as an initial path element.
870
- auto rootType = equivClass->getAnchor (builder, { });
871
- assert (hasConformanceInSignature (getRequirements (), rootType, protocol));
872
- path.emplace_back (rootType, protocol);
873
- } else {
874
- // This conformance comes from a derived source.
875
- //
876
- // To recover this the conformance, we recursively recover the conformance
877
- // of the parent type to the parent protocol first.
878
- auto parentPath = getConformanceAccessPath (
879
- shortestParentType, shortestParentProto);
880
- for (auto entry : parentPath)
881
- path.push_back (entry);
882
-
883
- // Then, we add the subject type from the parent protocol's requirement
884
- // signature.
885
- path.emplace_back (shortestSubjectType, protocol);
886
- }
865
+ auto parentPath = getConformanceAccessPath (
866
+ shortestParentType, shortestParentProto);
867
+ for (auto entry : parentPath)
868
+ path.push_back (entry);
887
869
888
- ConformanceAccessPath result (getASTContext ().AllocateCopy (path));
870
+ // Then, we add the subject type from the parent protocol's requirement
871
+ // signature.
872
+ path.emplace_back (shortestSubjectType, protocol);
889
873
874
+ ConformanceAccessPath result (builder.getASTContext ().AllocateCopy (path));
890
875
equivClass->conformanceAccessPathCache .insert ({protocol, result});
876
+
891
877
return result;
892
878
}
893
879
0 commit comments