63
63
using namespace swift ;
64
64
using namespace rewriting ;
65
65
66
+ // / This papers over a behavioral difference between
67
+ // / GenericSignature::getRequiredProtocols() and ArchetypeType::getConformsTo();
68
+ // / the latter drops any protocols to which the superclass requirement
69
+ // / conforms to concretely.
70
+ llvm::TinyPtrVector<const ProtocolDecl *>
71
+ EquivalenceClass::getConformsToExcludingSuperclassConformances () const {
72
+ llvm::TinyPtrVector<const ProtocolDecl *> result;
73
+
74
+ if (SuperclassConformances.empty ()) {
75
+ result = ConformsTo;
76
+ return result;
77
+ }
78
+
79
+ // The conformances in SuperclassConformances should appear in the same order
80
+ // as the protocols in ConformsTo.
81
+ auto conformanceIter = SuperclassConformances.begin ();
82
+
83
+ for (const auto *proto : ConformsTo) {
84
+ if (conformanceIter == SuperclassConformances.end ()) {
85
+ result.push_back (proto);
86
+ continue ;
87
+ }
88
+
89
+ if (proto == (*conformanceIter)->getProtocol ()) {
90
+ ++conformanceIter;
91
+ continue ;
92
+ }
93
+
94
+ result.push_back (proto);
95
+ }
96
+
97
+ assert (conformanceIter == SuperclassConformances.end ());
98
+ return result;
99
+ }
100
+
66
101
void EquivalenceClass::dump (llvm::raw_ostream &out) const {
67
102
out << Key << " => {" ;
68
103
@@ -650,6 +685,7 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParents(
650
685
equivClass->ConcreteType ->getConcreteType (),
651
686
equivClass->ConcreteType ->getSubstitutions (),
652
687
equivClass->getConformsTo (),
688
+ equivClass->ConcreteConformances ,
653
689
inducedRules);
654
690
}
655
691
@@ -664,6 +700,7 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParents(
664
700
equivClass->Superclass ->getSuperclass (),
665
701
equivClass->Superclass ->getSubstitutions (),
666
702
equivClass->getConformsTo (),
703
+ equivClass->SuperclassConformances ,
667
704
inducedRules);
668
705
}
669
706
}
@@ -705,6 +742,7 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParent(
705
742
const MutableTerm &key, RequirementKind requirementKind,
706
743
CanType concreteType, ArrayRef<Term> substitutions,
707
744
ArrayRef<const ProtocolDecl *> conformsTo,
745
+ llvm::TinyPtrVector<ProtocolConformance *> &conformances,
708
746
SmallVectorImpl<std::pair<MutableTerm, MutableTerm>> &inducedRules) const {
709
747
assert (requirementKind == RequirementKind::SameType ||
710
748
requirementKind == RequirementKind::Superclass);
@@ -730,12 +768,16 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParent(
730
768
// opaque result type?
731
769
assert (!conformance.isAbstract ());
732
770
771
+ auto *concrete = conformance.getConcrete ();
772
+
773
+ // Record the conformance for use by
774
+ // EquivalenceClass::getConformsToExcludingSuperclassConformances().
775
+ conformances.push_back (concrete);
776
+
733
777
auto assocTypes = Protos.getProtocolInfo (proto).AssociatedTypes ;
734
778
if (assocTypes.empty ())
735
779
continue ;
736
780
737
- auto *concrete = conformance.getConcrete ();
738
-
739
781
for (auto *assocType : assocTypes) {
740
782
if (DebugConcretizeNestedTypes) {
741
783
llvm::dbgs () << " ^^ " << " Looking up type witness for "
0 commit comments