6363using namespace swift ;
6464using namespace rewriting ;
6565
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+
66101void EquivalenceClass::dump (llvm::raw_ostream &out) const {
67102 out << Key << " => {" ;
68103
@@ -650,6 +685,7 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParents(
650685 equivClass->ConcreteType ->getConcreteType (),
651686 equivClass->ConcreteType ->getSubstitutions (),
652687 equivClass->getConformsTo (),
688+ equivClass->ConcreteConformances ,
653689 inducedRules);
654690 }
655691
@@ -664,6 +700,7 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParents(
664700 equivClass->Superclass ->getSuperclass (),
665701 equivClass->Superclass ->getSubstitutions (),
666702 equivClass->getConformsTo (),
703+ equivClass->SuperclassConformances ,
667704 inducedRules);
668705 }
669706 }
@@ -705,6 +742,7 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParent(
705742 const MutableTerm &key, RequirementKind requirementKind,
706743 CanType concreteType, ArrayRef<Term> substitutions,
707744 ArrayRef<const ProtocolDecl *> conformsTo,
745+ llvm::TinyPtrVector<ProtocolConformance *> &conformances,
708746 SmallVectorImpl<std::pair<MutableTerm, MutableTerm>> &inducedRules) const {
709747 assert (requirementKind == RequirementKind::SameType ||
710748 requirementKind == RequirementKind::Superclass);
@@ -730,12 +768,16 @@ void EquivalenceClassMap::concretizeNestedTypesFromConcreteParent(
730768 // opaque result type?
731769 assert (!conformance.isAbstract ());
732770
771+ auto *concrete = conformance.getConcrete ();
772+
773+ // Record the conformance for use by
774+ // EquivalenceClass::getConformsToExcludingSuperclassConformances().
775+ conformances.push_back (concrete);
776+
733777 auto assocTypes = Protos.getProtocolInfo (proto).AssociatedTypes ;
734778 if (assocTypes.empty ())
735779 continue ;
736780
737- auto *concrete = conformance.getConcrete ();
738-
739781 for (auto *assocType : assocTypes) {
740782 if (DebugConcretizeNestedTypes) {
741783 llvm::dbgs () << " ^^ " << " Looking up type witness for "
0 commit comments