Skip to content

Commit 0a60e7d

Browse files
committed
Sema: General cleanup for lookupVisibleMemberDecls()
- Pass around NominalTypeDecl instead of Type in a few places - Map type parameters to archetypes early instead of passing around a generic signature
1 parent e39dd6a commit 0a60e7d

File tree

1 file changed

+63
-103
lines changed

1 file changed

+63
-103
lines changed

lib/Sema/LookupVisibleDecls.cpp

Lines changed: 63 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "clang/AST/DeclObjC.h"
2020
#include "swift/AST/ASTContext.h"
2121
#include "swift/AST/ClangModuleLoader.h"
22+
#include "swift/AST/GenericEnvironment.h"
2223
#include "swift/AST/GenericSignature.h"
2324
#include "swift/AST/ImportCache.h"
2425
#include "swift/AST/Initializer.h"
@@ -238,15 +239,13 @@ static void collectVisibleMemberDecls(const DeclContext *CurrDC, LookupState LS,
238239
/// Lookup members in extensions of \p LookupType, using \p BaseType as the
239240
/// underlying type when checking any constraints on the extensions.
240241
static void doGlobalExtensionLookup(Type BaseType,
241-
Type LookupType,
242+
NominalTypeDecl *LookupType,
242243
SmallVectorImpl<ValueDecl *> &FoundDecls,
243244
const DeclContext *CurrDC,
244245
LookupState LS,
245246
DeclVisibilityKind Reason) {
246-
auto nominal = LookupType->getAnyNominal();
247-
248247
// Look in each extension of this type.
249-
for (auto extension : nominal->getExtensions()) {
248+
for (auto extension : LookupType->getExtensions()) {
250249
if (!evaluateOrDefault(CurrDC->getASTContext().evaluator,
251250
IsDeclApplicableRequest(DeclApplicabilityOwner(CurrDC, BaseType,
252251
extension)), false))
@@ -265,17 +264,17 @@ static void doGlobalExtensionLookup(Type BaseType,
265264
/// Don't do lookup into superclasses or implemented protocols. Uses
266265
/// \p BaseType as the underlying type when checking any constraints on the
267266
/// extensions.
268-
static void lookupTypeMembers(Type BaseType, Type LookupType,
267+
static void lookupTypeMembers(Type BaseType, NominalTypeDecl *LookupType,
269268
VisibleDeclConsumer &Consumer,
270269
const DeclContext *CurrDC, LookupState LS,
271270
DeclVisibilityKind Reason) {
272-
NominalTypeDecl *D = LookupType->getAnyNominal();
273-
assert(D && "should have a nominal type");
271+
assert(!BaseType->hasTypeParameter());
272+
assert(LookupType && "should have a nominal type");
274273

275-
Consumer.onLookupNominalTypeMembers(D, Reason);
274+
Consumer.onLookupNominalTypeMembers(LookupType, Reason);
276275

277276
SmallVector<ValueDecl*, 2> FoundDecls;
278-
collectVisibleMemberDecls(CurrDC, LS, BaseType, D, FoundDecls);
277+
collectVisibleMemberDecls(CurrDC, LS, BaseType, LookupType, FoundDecls);
279278

280279
doGlobalExtensionLookup(BaseType, LookupType, FoundDecls, CurrDC, LS, Reason);
281280

@@ -527,7 +526,7 @@ static void lookupDeclsFromProtocolsBeingConformedTo(
527526
// Add members from any extensions.
528527
if (LS.isIncludingProtocolExtensionMembers()) {
529528
SmallVector<ValueDecl *, 2> FoundDecls;
530-
doGlobalExtensionLookup(BaseTy, Proto->getDeclaredInterfaceType(),
529+
doGlobalExtensionLookup(BaseTy, Proto,
531530
FoundDecls, FromContext, LS,
532531
ReasonForThisProtocol);
533532
for (auto *VD : FoundDecls)
@@ -537,29 +536,20 @@ static void lookupDeclsFromProtocolsBeingConformedTo(
537536
}
538537

539538
static void
540-
lookupVisibleMemberDeclsImpl(Type BaseTy, VisibleDeclConsumer &Consumer,
541-
const DeclContext *CurrDC, LookupState LS,
542-
DeclVisibilityKind Reason,
543-
GenericSignature Sig,
544-
VisitedSet &Visited);
545-
546-
static void
547-
lookupVisibleProtocolMemberDecls(Type BaseTy, const ProtocolDecl *PD,
539+
lookupVisibleProtocolMemberDecls(Type BaseTy, ProtocolDecl *PD,
548540
VisibleDeclConsumer &Consumer,
549541
const DeclContext *CurrDC, LookupState LS,
550542
DeclVisibilityKind Reason,
551-
GenericSignature Sig,
552543
VisitedSet &Visited) {
553544
if (!Visited.insert(PD).second)
554545
return;
555546

556-
lookupTypeMembers(BaseTy, PD->getDeclaredInterfaceType(), Consumer, CurrDC,
557-
LS, Reason);
547+
lookupTypeMembers(BaseTy, PD, Consumer, CurrDC, LS, Reason);
558548

559549
// Collect members from the inherited protocols.
560550
for (auto Proto : PD->getInheritedProtocols())
561551
lookupVisibleProtocolMemberDecls(BaseTy, Proto, Consumer, CurrDC, LS,
562-
getReasonForSuper(Reason), Sig, Visited);
552+
getReasonForSuper(Reason), Visited);
563553
}
564554

565555
static void lookupVisibleCxxNamespaceMemberDecls(
@@ -621,10 +611,10 @@ static void lookupVisibleCxxNamespaceMemberDecls(
621611

622612
static void lookupVisibleMemberDeclsImpl(
623613
Type BaseTy, VisibleDeclConsumer &Consumer, const DeclContext *CurrDC,
624-
LookupState LS, DeclVisibilityKind Reason, GenericSignature Sig,
625-
VisitedSet &Visited) {
614+
LookupState LS, DeclVisibilityKind Reason, VisitedSet &Visited) {
626615
// Just look through l-valueness. It doesn't affect name lookup.
627616
assert(BaseTy && "lookup into null type");
617+
assert(!BaseTy->hasTypeParameter());
628618
assert(!BaseTy->hasLValueType());
629619

630620
// Handle metatype references, as in "some_type.some_member". These are
@@ -651,8 +641,7 @@ static void lookupVisibleMemberDeclsImpl(
651641
// anything else. For example, type SomeTy.SomeMember can look up static
652642
// functions, and can even look up non-static functions as well (thus
653643
// getting the address of the member).
654-
lookupVisibleMemberDeclsImpl(Ty, Consumer, CurrDC, subLS, Reason,
655-
Sig, Visited);
644+
lookupVisibleMemberDeclsImpl(Ty, Consumer, CurrDC, subLS, Reason, Visited);
656645
return;
657646
}
658647

@@ -675,23 +664,22 @@ static void lookupVisibleMemberDeclsImpl(
675664
// If the base is a protocol, enumerate its members.
676665
if (ProtocolType *PT = BaseTy->getAs<ProtocolType>()) {
677666
lookupVisibleProtocolMemberDecls(BaseTy, PT->getDecl(),
678-
Consumer, CurrDC, LS, Reason,
679-
Sig, Visited);
667+
Consumer, CurrDC, LS, Reason, Visited);
680668
return;
681669
}
682670

683671
// If the base is a protocol composition, enumerate members of the protocols.
684672
if (auto PC = BaseTy->getAs<ProtocolCompositionType>()) {
685673
for (auto Member : PC->getMembers())
686674
lookupVisibleMemberDeclsImpl(Member, Consumer, CurrDC, LS, Reason,
687-
Sig, Visited);
675+
Visited);
688676
return;
689677
}
690678

691679
if (auto *existential = BaseTy->getAs<ExistentialType>()) {
692680
auto constraint = existential->getConstraintType();
693681
lookupVisibleMemberDeclsImpl(constraint, Consumer, CurrDC, LS, Reason,
694-
Sig, Visited);
682+
Visited);
695683
return;
696684
}
697685

@@ -700,11 +688,11 @@ static void lookupVisibleMemberDeclsImpl(
700688
for (auto Proto : Archetype->getConformsTo())
701689
lookupVisibleProtocolMemberDecls(
702690
BaseTy, Proto, Consumer, CurrDC, LS,
703-
Reason, Sig, Visited);
691+
Reason, Visited);
704692

705693
if (auto superclass = Archetype->getSuperclass())
706694
lookupVisibleMemberDeclsImpl(superclass, Consumer, CurrDC, LS,
707-
Reason, Sig, Visited);
695+
Reason, Visited);
708696
return;
709697
}
710698

@@ -718,88 +706,53 @@ static void lookupVisibleMemberDeclsImpl(
718706
}
719707
}
720708

721-
// If we're looking into a type parameter and we have a GenericSignature,
722-
// query the signature to resolve where we should look.
723-
if (BaseTy->isTypeParameter() && Sig) {
724-
// The type might be fully concrete via a same-type requirement.
725-
if (auto ConcreteTy = Sig->getConcreteType(BaseTy)) {
726-
BaseTy = ConcreteTy;
727-
} else {
728-
// Look into protocols of conformance requirements
729-
for (const auto *Proto : Sig->getRequiredProtocols(BaseTy)) {
730-
lookupVisibleProtocolMemberDecls(
731-
BaseTy, Proto, Consumer, CurrDC,
732-
LS, getReasonForSuper(Reason), Sig, Visited);
733-
}
734-
735-
// Look into the superclass requirement type, if there is one.
736-
if (auto SuperclassTy = Sig->getSuperclassBound(BaseTy)) {
737-
lookupVisibleMemberDeclsImpl(SuperclassTy, Consumer, CurrDC,
738-
LS, getReasonForSuper(Reason),
739-
Sig, Visited);
740-
}
741-
742-
return;
743-
}
744-
}
745-
746709
// The members of a dynamic 'Self' type are the members of its static
747710
// class type.
748711
if (auto *const DS = BaseTy->getAs<DynamicSelfType>()) {
749712
BaseTy = DS->getSelfType();
750713
}
751714

752-
auto lookupTy = BaseTy;
715+
auto *NTD = BaseTy->getAnyNominal();
716+
if (NTD == nullptr)
717+
return;
753718

754-
llvm::SmallPtrSet<ClassDecl *, 8> Ancestors;
755-
{
756-
const auto NTD = BaseTy->getAnyNominal();
757-
if (NTD == nullptr)
758-
return;
719+
lookupTypeMembers(BaseTy, NTD, Consumer, CurrDC, LS, Reason);
759720

760-
lookupTypeMembers(BaseTy, lookupTy, Consumer, CurrDC, LS, Reason);
721+
// Look into protocols only on the current nominal to avoid repeatedly
722+
// visiting inherited conformances.
723+
lookupDeclsFromProtocolsBeingConformedTo(BaseTy, Consumer, LS, CurrDC,
724+
Reason, Visited);
761725

762-
// Look into protocols only on the current nominal to avoid repeatedly
763-
// visiting inherited conformances.
764-
lookupDeclsFromProtocolsBeingConformedTo(BaseTy, Consumer, LS, CurrDC,
765-
Reason, Visited);
726+
auto *CD = dyn_cast<ClassDecl>(NTD);
766727

767-
const auto CD = dyn_cast<ClassDecl>(NTD);
728+
if (!CD || !CD->hasSuperclass())
729+
return;
768730

769-
// FIXME: We check `getSuperclass()` here because we'll be using the
770-
// superclass Type below, and in ill-formed code `hasSuperclass()` could
771-
// be true while `getSuperclass()` returns null, because the latter
772-
// looks for a declaration.
773-
if (!CD || !CD->getSuperclass())
774-
return;
731+
// We have a superclass; switch state and look into the inheritance chain.
732+
llvm::SmallPtrSet<ClassDecl *, 8> Ancestors;
733+
Ancestors.insert(CD);
775734

776-
// We have a superclass; switch state and look into the inheritance chain.
777-
Ancestors.insert(CD);
735+
Reason = getReasonForSuper(Reason);
778736

779-
Reason = getReasonForSuper(Reason);
780-
lookupTy = CD->getSuperclass();
737+
LS = LS.withOnSuperclass();
738+
if (CD->inheritsSuperclassInitializers())
739+
LS = LS.withInheritsSuperclassInitializers();
781740

782-
LS = LS.withOnSuperclass();
783-
if (CD->inheritsSuperclassInitializers())
784-
LS = LS.withInheritsSuperclassInitializers();
785-
}
741+
CD = CD->getSuperclassDecl();
786742

787743
// Look into the inheritance chain.
788744
do {
789-
const auto CurClass = lookupTy->getClassOrBoundGenericClass();
790-
791745
// FIXME: This path is no substitute for an actual circularity check.
792746
// The real fix is to check that the superclass doesn't introduce a
793747
// circular reference before it's written into the AST.
794-
if (!Ancestors.insert(CurClass).second)
748+
if (!Ancestors.insert(CD).second)
795749
break;
796750

797-
lookupTypeMembers(BaseTy, lookupTy, Consumer, CurrDC, LS, Reason);
751+
lookupTypeMembers(BaseTy, CD, Consumer, CurrDC, LS, Reason);
798752

799-
lookupTy = CurClass->getSuperclass();
800-
if (!CurClass->inheritsSuperclassInitializers())
753+
if (!CD->inheritsSuperclassInitializers())
801754
LS = LS.withoutInheritsSuperclassInitializers();
802-
} while (lookupTy);
755+
} while ((CD = CD->getSuperclassDecl()));
803756
}
804757

805758
swift::DynamicLookupInfo::DynamicLookupInfo(
@@ -1121,8 +1074,7 @@ struct KeyPathDynamicMemberConsumer : public VisibleDeclConsumer {
11211074
static void lookupVisibleDynamicMemberLookupDecls(
11221075
Type baseType, SourceLoc loc, KeyPathDynamicMemberConsumer &consumer,
11231076
const DeclContext *dc, LookupState LS, DeclVisibilityKind reason,
1124-
GenericSignature Sig, VisitedSet &visited,
1125-
llvm::DenseSet<TypeBase *> &seenDynamicLookup);
1077+
VisitedSet &visited, llvm::DenseSet<TypeBase *> &seenDynamicLookup);
11261078

11271079
/// Enumerates all members of \c baseType, including both directly visible and
11281080
/// members visible by keypath dynamic member lookup.
@@ -1132,11 +1084,12 @@ static void lookupVisibleDynamicMemberLookupDecls(
11321084
static void lookupVisibleMemberAndDynamicMemberDecls(
11331085
Type baseType, SourceLoc loc, VisibleDeclConsumer &consumer,
11341086
KeyPathDynamicMemberConsumer &dynamicMemberConsumer, const DeclContext *DC,
1135-
LookupState LS, DeclVisibilityKind reason, GenericSignature Sig,
1087+
LookupState LS, DeclVisibilityKind reason,
11361088
VisitedSet &visited, llvm::DenseSet<TypeBase *> &seenDynamicLookup) {
1137-
lookupVisibleMemberDeclsImpl(baseType, consumer, DC, LS, reason, Sig, visited);
1089+
1090+
lookupVisibleMemberDeclsImpl(baseType, consumer, DC, LS, reason, visited);
11381091
lookupVisibleDynamicMemberLookupDecls(baseType, loc, dynamicMemberConsumer,
1139-
DC, LS, reason, Sig, visited,
1092+
DC, LS, reason, visited,
11401093
seenDynamicLookup);
11411094
}
11421095

@@ -1149,8 +1102,7 @@ static void lookupVisibleMemberAndDynamicMemberDecls(
11491102
static void lookupVisibleDynamicMemberLookupDecls(
11501103
Type baseType, SourceLoc loc, KeyPathDynamicMemberConsumer &consumer,
11511104
const DeclContext *dc, LookupState LS, DeclVisibilityKind reason,
1152-
GenericSignature Sig, VisitedSet &visited,
1153-
llvm::DenseSet<TypeBase *> &seenDynamicLookup) {
1105+
VisitedSet &visited, llvm::DenseSet<TypeBase *> &seenDynamicLookup) {
11541106
if (!seenDynamicLookup.insert(baseType.getPointer()).second)
11551107
return;
11561108

@@ -1187,7 +1139,7 @@ static void lookupVisibleDynamicMemberLookupDecls(
11871139
baseType);
11881140

11891141
lookupVisibleMemberAndDynamicMemberDecls(memberType, loc, consumer,
1190-
consumer, dc, LS, reason, Sig,
1142+
consumer, dc, LS, reason,
11911143
visited, seenDynamicLookup);
11921144
}
11931145
}
@@ -1201,7 +1153,9 @@ static void lookupVisibleDynamicMemberLookupDecls(
12011153
static void lookupVisibleMemberDecls(
12021154
Type BaseTy, SourceLoc loc, VisibleDeclConsumer &Consumer,
12031155
const DeclContext *CurrDC, LookupState LS,
1204-
DeclVisibilityKind Reason, GenericSignature Sig) {
1156+
DeclVisibilityKind Reason) {
1157+
assert(!BaseTy->hasTypeParameter());
1158+
12051159
OverrideFilteringConsumer overrideConsumer(BaseTy, CurrDC);
12061160
KeyPathDynamicMemberConsumer dynamicConsumer(
12071161
Consumer,
@@ -1211,7 +1165,7 @@ static void lookupVisibleMemberDecls(
12111165
llvm::DenseSet<TypeBase *> seenDynamicLookup;
12121166
lookupVisibleMemberAndDynamicMemberDecls(
12131167
BaseTy, loc, overrideConsumer, dynamicConsumer, CurrDC, LS, Reason,
1214-
Sig, Visited, seenDynamicLookup);
1168+
Visited, seenDynamicLookup);
12151169

12161170
// Report the declarations we found to the real consumer.
12171171
overrideConsumer.filterDecls(Consumer);
@@ -1325,7 +1279,7 @@ static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
13251279

13261280
if (ExtendedType) {
13271281
::lookupVisibleMemberDecls(ExtendedType, Loc, Consumer, DC, LS,
1328-
MemberReason, nullptr);
1282+
MemberReason);
13291283

13301284
// Going outside the current type context.
13311285
MemberReason = DeclVisibilityKind::MemberOfOutsideNominal;
@@ -1386,6 +1340,13 @@ void swift::lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer, Type BaseTy,
13861340
bool includeDerivedRequirements,
13871341
bool includeProtocolExtensionMembers,
13881342
GenericSignature Sig) {
1343+
// If we have an interface type, map it into its primary environment before
1344+
// doing anything else.
1345+
if (BaseTy->hasTypeParameter()) {
1346+
assert(Sig);
1347+
BaseTy = Sig.getGenericEnvironment()->mapTypeIntoContext(BaseTy);
1348+
}
1349+
13891350
assert(CurrDC);
13901351
LookupState ls = LookupState::makeQualified();
13911352
if (includeInstanceMembers) {
@@ -1399,6 +1360,5 @@ void swift::lookupVisibleMemberDecls(VisibleDeclConsumer &Consumer, Type BaseTy,
13991360
}
14001361

14011362
::lookupVisibleMemberDecls(BaseTy, loc, Consumer, CurrDC, ls,
1402-
DeclVisibilityKind::MemberOfCurrentNominal,
1403-
Sig);
1363+
DeclVisibilityKind::MemberOfCurrentNominal);
14041364
}

0 commit comments

Comments
 (0)