Skip to content

Commit e307860

Browse files
committed
IDE: Stop calling getAllConformances() on protocols
1 parent eb77da1 commit e307860

File tree

3 files changed

+39
-24
lines changed

3 files changed

+39
-24
lines changed

lib/IDE/CodeCompletionResultType.cpp

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -208,32 +208,45 @@ const USRBasedType *USRBasedType::fromType(Type Ty, USRBasedTypeArena &Arena) {
208208
}
209209

210210
SmallVector<const USRBasedType *, 2> Supertypes;
211+
;
211212
if (auto Nominal = Ty->getAnyNominal()) {
212-
auto Conformances = Nominal->getAllConformances();
213-
Supertypes.reserve(Conformances.size());
214-
for (auto Conformance : Conformances) {
215-
if (Conformance->getDeclContext()->getParentModule() !=
216-
Nominal->getModuleContext()) {
217-
// Only include conformances that are declared within the module of the
218-
// type to avoid caching retroactive conformances which might not
219-
// exist when using the code completion cache from a different module.
220-
continue;
221-
}
222-
if (Conformance->getProtocol()->isSpecificProtocol(KnownProtocolKind::Sendable)) {
223-
// FIXME: Sendable conformances are lazily synthesized as they are
224-
// needed by the compiler. Depending on whether we checked whether a
225-
// type conforms to Sendable before constructing the USRBasedType, we
226-
// get different results for its conformance. For now, always drop the
227-
// Sendable conformance.
228-
continue;
213+
if (auto *Proto = dyn_cast<ProtocolDecl>(Nominal)) {
214+
Proto->walkInheritedProtocols([&](ProtocolDecl *inherited) {
215+
if (Proto != inherited &&
216+
!inherited->isSpecificProtocol(KnownProtocolKind::Sendable)) {
217+
Supertypes.push_back(USRBasedType::fromType(
218+
inherited->getDeclaredInterfaceType(), Arena));
219+
}
220+
221+
return TypeWalker::Action::Continue;
222+
});
223+
} else {
224+
auto Conformances = Nominal->getAllConformances();
225+
Supertypes.reserve(Conformances.size());
226+
for (auto Conformance : Conformances) {
227+
if (Conformance->getDeclContext()->getParentModule() !=
228+
Nominal->getModuleContext()) {
229+
// Only include conformances that are declared within the module of the
230+
// type to avoid caching retroactive conformances which might not
231+
// exist when using the code completion cache from a different module.
232+
continue;
233+
}
234+
if (Conformance->getProtocol()->isSpecificProtocol(KnownProtocolKind::Sendable)) {
235+
// FIXME: Sendable conformances are lazily synthesized as they are
236+
// needed by the compiler. Depending on whether we checked whether a
237+
// type conforms to Sendable before constructing the USRBasedType, we
238+
// get different results for its conformance. For now, always drop the
239+
// Sendable conformance.
240+
continue;
241+
}
242+
Supertypes.push_back(USRBasedType::fromType(
243+
Conformance->getProtocol()->getDeclaredInterfaceType(), Arena));
229244
}
230-
Supertypes.push_back(USRBasedType::fromType(
231-
Conformance->getProtocol()->getDeclaredInterfaceType(), Arena));
232245
}
233246
}
234247

235248
// You would think that superclass + conformances form a DAG. You are wrong!
236-
// We can achieve a circular supertype hierarcy with
249+
// We can achieve a circular supertype hierarchy with
237250
//
238251
// protocol Proto : Class {}
239252
// class Class : Proto {}

lib/IDE/CompletionLookup.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,7 +2483,7 @@ void CompletionLookup::addTypeRelationFromProtocol(
24832483

24842484
// The literal can produce any type that conforms to its ExpressibleBy
24852485
// protocol. Figure out as which type we want to show it in code completion.
2486-
auto *P = Ctx.getProtocol(protocolForLiteralKind(kind));
2486+
auto *PD = Ctx.getProtocol(protocolForLiteralKind(kind));
24872487
for (auto T : expectedTypeContext.getPossibleTypes()) {
24882488
if (!T)
24892489
continue;
@@ -2497,9 +2497,8 @@ void CompletionLookup::addTypeRelationFromProtocol(
24972497
}
24982498

24992499
// Check for conformance to the literal protocol.
2500-
if (auto *NTD = T->getAnyNominal()) {
2501-
SmallVector<ProtocolConformance *, 2> conformances;
2502-
if (NTD->lookupConformance(P, conformances)) {
2500+
if (T->getAnyNominal()) {
2501+
if (CurrModule->lookupConformance(T, PD)) {
25032502
literalType = T;
25042503
break;
25052504
}

lib/IDE/CompletionOverrideLookup.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ void CompletionOverrideLookup::addAssociatedTypes(NominalTypeDecl *NTD) {
411411
hasOverride || hasOverridabilityModifier || hasStaticOrClass))
412412
return;
413413

414+
if (isa<ProtocolDecl>(NTD))
415+
return;
416+
414417
for (auto Conformance : NTD->getAllConformances()) {
415418
auto Proto = Conformance->getProtocol();
416419
if (!Proto->isAccessibleFrom(CurrDeclContext))

0 commit comments

Comments
 (0)