Skip to content

Commit 82e7631

Browse files
committed
Sema: Narrow down search for abstract type witnesses to local conformances only
1 parent fcda8bc commit 82e7631

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
21702182
void 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,
40704085
static NormalProtocolConformance *
40714086
getBetterConformanceForResolvingTypeWitnesses(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

Comments
 (0)