Skip to content

Commit 021cbbb

Browse files
authored
Merge pull request swiftlang#30530 from AnthonyLatsis/member-lookup-protocols
[CodeCompletion] Optimize member lookup in protocols being conformed to
2 parents 7bc4148 + be4ad49 commit 021cbbb

File tree

1 file changed

+46
-33
lines changed

1 file changed

+46
-33
lines changed

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,9 @@ static void lookupDeclsFromProtocolsBeingConformedTo(
415415
}
416416

417417
DeclVisibilityKind ReasonForThisProtocol;
418-
if (Reason == DeclVisibilityKind::MemberOfCurrentNominal)
418+
if (Conformance->getKind() == ProtocolConformanceKind::Inherited)
419+
ReasonForThisProtocol = getReasonForSuper(Reason);
420+
else if (Reason == DeclVisibilityKind::MemberOfCurrentNominal)
419421
ReasonForThisProtocol =
420422
DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal;
421423
else
@@ -629,50 +631,61 @@ static void lookupVisibleMemberDeclsImpl(
629631
}
630632
}
631633

632-
llvm::SmallPtrSet<ClassDecl *, 8> Ancestors;
633-
do {
634-
NominalTypeDecl *CurNominal = BaseTy->getAnyNominal();
635-
if (!CurNominal)
636-
break;
637-
638-
synthesizeMemberDeclsForLookup(CurNominal, CurrDC);
634+
const auto synthesizeAndLookupTypeMembers = [&](NominalTypeDecl *NTD) {
635+
synthesizeMemberDeclsForLookup(NTD, CurrDC);
639636

640637
// Look in for members of a nominal type.
641638
lookupTypeMembers(BaseTy, BaseTy, Consumer, CurrDC, LS, Reason);
639+
};
640+
641+
llvm::SmallPtrSet<ClassDecl *, 8> Ancestors;
642+
{
643+
const auto NTD = BaseTy->getAnyNominal();
644+
if (NTD == nullptr)
645+
return;
646+
647+
synthesizeAndLookupTypeMembers(NTD);
648+
// Look into protocols only on the current nominal to avoid repeatedly
649+
// visiting inherited conformances.
642650
lookupDeclsFromProtocolsBeingConformedTo(BaseTy, Consumer, LS, CurrDC,
643651
Reason, Visited);
644-
// If we have a class type, look into its superclass.
645-
auto *CurClass = dyn_cast<ClassDecl>(CurNominal);
652+
653+
const auto CD = dyn_cast<ClassDecl>(NTD);
646654

647655
// FIXME: We check `getSuperclass()` here because we'll be using the
648656
// superclass Type below, and in ill-formed code `hasSuperclass()` could
649657
// be true while `getSuperclass()` returns null, because the latter
650658
// looks for a declaration.
651-
if (CurClass && CurClass->getSuperclass()) {
652-
// FIXME: This path is no substitute for an actual circularity check.
653-
// The real fix is to check that the superclass doesn't introduce a
654-
// circular reference before it's written into the AST.
655-
if (Ancestors.count(CurClass)) {
656-
break;
657-
}
659+
if (!CD || !CD->getSuperclass())
660+
return;
658661

659-
BaseTy = CurClass->getSuperclass();
660-
Reason = getReasonForSuper(Reason);
661-
662-
bool InheritsSuperclassInitializers =
663-
CurClass->inheritsSuperclassInitializers();
664-
if (LS.isOnSuperclass() && !InheritsSuperclassInitializers)
665-
LS = LS.withoutInheritsSuperclassInitializers();
666-
else if (!LS.isOnSuperclass()) {
667-
LS = LS.withOnSuperclass();
668-
if (InheritsSuperclassInitializers)
669-
LS = LS.withInheritsSuperclassInitializers();
670-
}
671-
} else {
662+
// We have a superclass; switch state and look into the inheritance chain.
663+
Ancestors.insert(CD);
664+
665+
Reason = getReasonForSuper(Reason);
666+
BaseTy = CD->getSuperclass();
667+
668+
LS = LS.withOnSuperclass();
669+
if (CD->inheritsSuperclassInitializers())
670+
LS = LS.withInheritsSuperclassInitializers();
671+
}
672+
673+
// Look into the inheritance chain.
674+
do {
675+
const auto CurClass = BaseTy->getClassOrBoundGenericClass();
676+
677+
// FIXME: This path is no substitute for an actual circularity check.
678+
// The real fix is to check that the superclass doesn't introduce a
679+
// circular reference before it's written into the AST.
680+
if (!Ancestors.insert(CurClass).second)
672681
break;
673-
}
674-
Ancestors.insert(CurClass);
675-
} while (1);
682+
683+
synthesizeAndLookupTypeMembers(CurClass);
684+
685+
BaseTy = CurClass->getSuperclass();
686+
if (!CurClass->inheritsSuperclassInitializers())
687+
LS = LS.withoutInheritsSuperclassInitializers();
688+
} while (BaseTy);
676689
}
677690

678691
swift::DynamicLookupInfo::DynamicLookupInfo(

0 commit comments

Comments
 (0)