@@ -2167,6 +2167,18 @@ AssociatedTypeInference::computeAbstractTypeWitness(
21672167 return llvm::None;
21682168}
21692169
2170+ static SmallVector<ProtocolConformance *, 2 >
2171+ getPeerConformances (NormalProtocolConformance *conformance) {
2172+ auto *dc = conformance->getDeclContext ();
2173+ IterableDeclContext *idc = dyn_cast<ExtensionDecl>(dc);
2174+ if (!idc)
2175+ idc = cast<NominalTypeDecl>(dc);
2176+
2177+ // NonStructural skips the Sendable synthesis which can cycle, and Sendable
2178+ // doesn't have associated types anyway.
2179+ return idc->getLocalConformances (ConformanceLookupKind::NonStructural);
2180+ }
2181+
21702182void AssociatedTypeInference::collectAbstractTypeWitnesses (
21712183 TypeWitnessSystem &system,
21722184 ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const {
@@ -2212,10 +2224,13 @@ void AssociatedTypeInference::collectAbstractTypeWitnesses(
22122224 // are less likely to cause request cycles.
22132225 considerProtocolRequirements (conformance->getProtocol ());
22142226
2215- // Also look through all other protocols the conforming type conforms to.
2216- for (auto *const conformedProto :
2217- dc->getSelfNominalTypeDecl ()->getAllProtocols (/* sorted=*/ true )) {
2218- considerProtocolRequirements (conformedProto);
2227+ // Look through all conformances in the same DeclContext as ours.
2228+ for (auto *otherConformance : getPeerConformances (conformance)) {
2229+ // Don't visit this one twice.
2230+ if (otherConformance->getProtocol () == conformance->getProtocol ())
2231+ continue ;
2232+
2233+ considerProtocolRequirements (otherConformance->getProtocol ());
22192234 }
22202235
22212236 // If the same-type constraints weren't enough to resolve an associated type,
@@ -4070,18 +4085,8 @@ ResolveTypeWitnessesRequest::evaluate(Evaluator &evaluator,
40704085static NormalProtocolConformance *
40714086getBetterConformanceForResolvingTypeWitnesses (NormalProtocolConformance *conformance,
40724087 AssociatedTypeDecl *requirement) {
4073- auto *dc = conformance->getDeclContext ();
4074- assert (dc->getParentSourceFile () && " What are you doing?" );
40754088 auto *proto = conformance->getProtocol ();
4076-
4077- IterableDeclContext *idc;
4078- if (auto *extensionDecl = dyn_cast<ExtensionDecl>(dc))
4079- idc = extensionDecl;
4080- else
4081- idc = cast<NominalTypeDecl>(dc);
4082-
4083- auto otherConformances = idc->getLocalConformances (ConformanceLookupKind::NonStructural);
4084- for (auto *otherConformance : otherConformances) {
4089+ for (auto *otherConformance : getPeerConformances (conformance)) {
40854090 auto *otherNormal = dyn_cast<NormalProtocolConformance>(
40864091 otherConformance->getRootConformance ());
40874092 if (otherNormal == nullptr )
0 commit comments