Skip to content

Commit 876738f

Browse files
authored
Merge pull request swiftlang#18718 from DougGregor/cleanup-type-lookup
[Name lookup] Clean up qualified and type lookup
2 parents d293845 + 8a81ea4 commit 876738f

File tree

10 files changed

+59
-120
lines changed

10 files changed

+59
-120
lines changed

include/swift/AST/DeclContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
500500
/// lookup.
501501
///
502502
/// \returns true if anything was found.
503-
bool lookupQualified(ArrayRef<NominalTypeDecl *> types, DeclName member,
503+
bool lookupQualified(ArrayRef<TypeDecl *> types, DeclName member,
504504
NLOptions options,
505505
SmallVectorImpl<ValueDecl *> &decls) const;
506506

include/swift/AST/LookupKinds.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,29 +37,25 @@ enum NLOptions : unsigned {
3737
/// Remove overridden declarations from the set of results.
3838
NL_RemoveOverridden = 0x08,
3939

40-
/// For existentials involving the special \c AnyObject protocol,
41-
/// allow lookups to find members of all classes.
42-
NL_DynamicLookup = 0x10,
43-
4440
/// Don't check access when doing lookup into a type.
4541
///
4642
/// This option is not valid when performing lookup into a module.
47-
NL_IgnoreAccessControl = 0x20,
43+
NL_IgnoreAccessControl = 0x10,
4844

4945
/// This lookup is known to be a non-cascading dependency, i.e. one that does
5046
/// not affect downstream files.
5147
///
5248
/// \see NL_KnownDependencyMask
53-
NL_KnownNonCascadingDependency = 0x40,
49+
NL_KnownNonCascadingDependency = 0x20,
5450

5551
/// This lookup is known to be a cascading dependency, i.e. one that can
5652
/// affect downstream files.
5753
///
5854
/// \see NL_KnownDependencyMask
59-
NL_KnownCascadingDependency = 0x80,
55+
NL_KnownCascadingDependency = 0x40,
6056

6157
/// This lookup should only return type declarations.
62-
NL_OnlyTypes = 0x100,
58+
NL_OnlyTypes = 0x80,
6359

6460
/// This lookup is known to not add any additional dependencies to the
6561
/// primary source file.

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2176,8 +2176,8 @@ TypeDecl *EquivalenceClass::lookupNestedType(
21762176
if (decl) {
21772177
SmallVector<ValueDecl *, 2> foundMembers;
21782178
decl->getParentModule()->lookupQualified(
2179-
typeToSearch, name,
2180-
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers, nullptr,
2179+
decl, name,
2180+
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers,
21812181
foundMembers);
21822182
for (auto member : foundMembers) {
21832183
if (auto type = dyn_cast<TypeDecl>(member)) {

lib/AST/NameLookup.cpp

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
716716
if (!nominal) continue;
717717

718718
// Dig out the type we're looking into.
719-
SmallVector<NominalTypeDecl *, 2> lookupDecls;
719+
SmallVector<TypeDecl *, 2> lookupDecls;
720720
lookupDecls.push_back(nominal);
721721

722722
// For a protocol extension, check whether there are additional
@@ -793,7 +793,7 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
793793
GenericParamList *GenericParams = nullptr;
794794

795795
// Dig out the type we're looking into.
796-
SmallVector<NominalTypeDecl *, 2> lookupDecls;
796+
SmallVector<TypeDecl *, 2> lookupDecls;
797797

798798
// Local function to populate the set of lookup declarations from
799799
// the given DeclContext.
@@ -1824,10 +1824,15 @@ bool DeclContext::lookupQualified(Type type,
18241824
SmallVector<NominalTypeDecl *, 4> nominalTypesToLookInto;
18251825
extractDirectlyReferencedNominalTypes(type, nominalTypesToLookInto);
18261826

1827-
return lookupQualified(nominalTypesToLookInto, member, options, decls);
1827+
SmallVector<TypeDecl *, 4> typeDeclsToLookInto;
1828+
typeDeclsToLookInto.reserve(nominalTypesToLookInto.size());
1829+
for (auto nominal : nominalTypesToLookInto)
1830+
typeDeclsToLookInto.push_back(nominal);
1831+
1832+
return lookupQualified(typeDeclsToLookInto, member, options, decls);
18281833
}
18291834

1830-
bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
1835+
bool DeclContext::lookupQualified(ArrayRef<TypeDecl *> typeDecls,
18311836
DeclName member,
18321837
NLOptions options,
18331838
SmallVectorImpl<ValueDecl *> &decls) const {
@@ -1856,12 +1861,33 @@ bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
18561861
return true;
18571862
};
18581863

1859-
// Look through the type declarations we were given, resolving
1864+
// Look through the type declarations we were given, resolving them down
1865+
// to nominal type declarations, module declarations, and
18601866
ASTContext &ctx = getASTContext();
1861-
for (auto nominal : typeDecls) {
1867+
SmallVector<ModuleDecl *, 2> moduleDecls;
1868+
bool anyObject = false;
1869+
auto nominalTypeDecls =
1870+
resolveTypeDeclsToNominal(ctx.evaluator, ctx, typeDecls, moduleDecls,
1871+
anyObject);
1872+
1873+
// If the only declaration we were given was AnyObject, this is AnyObject
1874+
// lookup.
1875+
if (anyObject && nominalTypeDecls.empty() && moduleDecls.empty())
1876+
return lookupAnyObject(member, options, decls);
1877+
1878+
// Add all of the nominal types to the stack.
1879+
for (auto nominal : nominalTypeDecls) {
18621880
addNominalType(nominal);
18631881
}
18641882

1883+
// Search all of the modules.
1884+
for (auto module : moduleDecls) {
1885+
auto innerOptions = options;
1886+
innerOptions &= ~NL_RemoveOverridden;
1887+
innerOptions &= ~NL_RemoveNonVisible;
1888+
lookupQualified(module, member, innerOptions, decls);
1889+
}
1890+
18651891
// Whether we only want to return complete object initializers.
18661892
bool onlyCompleteObjectInits = false;
18671893

@@ -1960,7 +1986,6 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclName member,
19601986
NLOptions options,
19611987
SmallVectorImpl<ValueDecl *> &decls) const {
19621988
using namespace namelookup;
1963-
assert(decls.empty() && "additive lookup not supported");
19641989

19651990
// Configure lookup and dig out the tracker.
19661991
ReferencedNameTracker *tracker = nullptr;
@@ -2185,14 +2210,6 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator,
21852210
ArrayRef<TypeDecl *> baseTypes,
21862211
DeclName name,
21872212
DeclContext *dc) {
2188-
// Look through the base types to find something on which we can perform
2189-
// qualified name lookup.
2190-
SmallVector<ModuleDecl *, 2> moduleBaseTypes;
2191-
bool anyObject = false;
2192-
auto nominalBaseTypes =
2193-
resolveTypeDeclsToNominal(evaluator, ctx, baseTypes, moduleBaseTypes,
2194-
anyObject);
2195-
21962213
DirectlyReferencedTypeDecls result;
21972214
auto addResults = [&result](ArrayRef<ValueDecl *> found){
21982215
for (auto decl : found){
@@ -2203,21 +2220,11 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator,
22032220
};
22042221

22052222
{
2206-
// Look through nominal types.
2207-
SmallVector<ValueDecl *, 4> nominalMembers;
2208-
auto options = NL_RemoveNonVisible | NL_OnlyTypes;
2209-
dc->lookupQualified(nominalBaseTypes, name, options, nominalMembers);
2210-
addResults(nominalMembers);
2211-
}
2212-
2213-
{
2214-
// Look through modules.
2223+
// Look into the base types.
2224+
SmallVector<ValueDecl *, 4> members;
22152225
auto options = NL_RemoveNonVisible | NL_OnlyTypes;
2216-
for (auto module : moduleBaseTypes) {
2217-
SmallVector<ValueDecl *, 4> moduleMembers;
2218-
dc->lookupQualified(module, name, options, moduleMembers);
2219-
addResults(moduleMembers);
2220-
}
2226+
dc->lookupQualified(baseTypes, name, options, members);
2227+
addResults(members);
22212228
}
22222229

22232230
return result;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4765,7 +4765,7 @@ namespace {
47654765
// If we're importing into the primary @interface for something, as
47664766
// opposed to an extension, make sure we don't try to load any
47674767
// categories...by just looking into the super type.
4768-
lookupContext = classDecl->getSuperclassDecl ();
4768+
lookupContext = classDecl->getSuperclassDecl();
47694769
}
47704770

47714771
if (lookupContext) {
@@ -7651,8 +7651,8 @@ void ClangImporter::Implementation::startedImportingEntity() {
76517651
static void finishTypeWitnesses(
76527652
NormalProtocolConformance *conformance) {
76537653
auto *dc = conformance->getDeclContext();
7654+
auto nominal = dc->getAsNominalTypeOrNominalTypeExtensionContext();
76547655
auto *module = dc->getParentModule();
7655-
auto &ctx = module->getASTContext();
76567656

76577657
auto *proto = conformance->getProtocol();
76587658
auto selfType = conformance->getType();
@@ -7669,8 +7669,8 @@ static void finishTypeWitnesses(
76697669
NL_OnlyTypes |
76707670
NL_ProtocolMembers);
76717671

7672-
dc->lookupQualified(selfType, assocType->getFullName(), options,
7673-
ctx.getLazyResolver(), lookupResults);
7672+
dc->lookupQualified(nominal, assocType->getFullName(), options,
7673+
lookupResults);
76747674
for (auto member : lookupResults) {
76757675
auto typeDecl = cast<TypeDecl>(member);
76767676
if (isa<AssociatedTypeDecl>(typeDecl)) continue;

lib/IDE/CodeCompletion.cpp

Lines changed: 8 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2909,6 +2909,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29092909
if (HaveLParen)
29102910
return;
29112911

2912+
LLVM_FALLTHROUGH;
2913+
2914+
case LookupKind::ValueInDeclContext:
2915+
case LookupKind::ImportFromModule:
29122916
if (auto *VD = dyn_cast<VarDecl>(D)) {
29132917
addVarDeclRef(VD, Reason);
29142918
return;
@@ -2943,7 +2947,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29432947

29442948
if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) {
29452949
addTypeAliasRef(TAD, Reason);
2946-
auto type = TAD->mapTypeIntoContext(TAD->getUnderlyingTypeLoc().getType());
2950+
auto type = TAD->mapTypeIntoContext(TAD->getDeclaredInterfaceType());
29472951
if (type->mayHaveMembers())
29482952
addConstructorCallsForType(type, TAD->getName(), Reason);
29492953
return;
@@ -2964,73 +2968,17 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29642968

29652969
if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
29662970
addEnumElementRef(EED, Reason, /*HasTypeContext=*/false);
2971+
return;
29672972
}
29682973

29692974
// Swift key path allows .[0]
29702975
if (shouldAddSubscriptCall()) {
29712976
if (auto *SD = dyn_cast<SubscriptDecl>(D)) {
2972-
if (ExprType->is<AnyMetatypeType>())
2973-
return;
2974-
addSubscriptCall(SD, Reason);
2975-
}
2976-
}
2977-
return;
2978-
2979-
case LookupKind::ValueInDeclContext:
2980-
case LookupKind::ImportFromModule:
2981-
if (auto *VD = dyn_cast<VarDecl>(D)) {
2982-
addVarDeclRef(VD, Reason);
2983-
return;
2984-
}
2985-
2986-
if (auto *FD = dyn_cast<FuncDecl>(D)) {
2987-
// We cannot call operators with a postfix parenthesis syntax.
2988-
if (FD->isBinaryOperator() || FD->isUnaryOperator())
2989-
return;
2990-
2991-
// We cannot call accessors. We use VarDecls and SubscriptDecls to
2992-
// produce completions that refer to getters and setters.
2993-
if (isa<AccessorDecl>(FD))
2994-
return;
2995-
2996-
// Do we want compound function names here?
2997-
if (shouldUseFunctionReference(FD)) {
2998-
addCompoundFunctionName(FD, Reason);
2977+
if (ExprType && !ExprType->is<AnyMetatypeType>())
2978+
addSubscriptCall(SD, Reason);
29992979
return;
30002980
}
3001-
3002-
addMethodCall(FD, Reason);
3003-
return;
3004-
}
3005-
3006-
if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
3007-
addNominalTypeRef(NTD, Reason);
3008-
addConstructorCallsForType(NTD->getDeclaredInterfaceType(),
3009-
NTD->getName(), Reason);
3010-
return;
30112981
}
3012-
3013-
if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) {
3014-
addTypeAliasRef(TAD, Reason);
3015-
auto type = TAD->mapTypeIntoContext(TAD->getDeclaredInterfaceType());
3016-
if (type->mayHaveMembers())
3017-
addConstructorCallsForType(type, TAD->getName(), Reason);
3018-
return;
3019-
}
3020-
3021-
if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) {
3022-
addGenericTypeParamRef(GP, Reason);
3023-
for (auto *protocol : GP->getConformingProtocols())
3024-
addConstructorCallsForType(protocol->getDeclaredInterfaceType(),
3025-
GP->getName(), Reason);
3026-
return;
3027-
}
3028-
3029-
if (auto *AT = dyn_cast<AssociatedTypeDecl>(D)) {
3030-
addAssociatedTypeRef(AT, Reason);
3031-
return;
3032-
}
3033-
30342982
return;
30352983

30362984
case LookupKind::EnumElement:

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -627,10 +627,6 @@ SmallVector<OverrideMatch, 2> OverrideMatcher::match(
627627
if (members.empty() || name != membersName) {
628628
auto lookupOptions = defaultMemberLookupOptions;
629629

630-
// Class methods cannot override declarations only
631-
// visible via dynamic dispatch.
632-
lookupOptions -= NameLookupFlags::DynamicLookup;
633-
634630
// Class methods cannot override declarations only
635631
// visible as protocol requirements or protocol
636632
// extension members.

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,6 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc,
370370
NLOptions subOptions = NL_QualifiedDefault;
371371
if (options.contains(NameLookupFlags::KnownPrivate))
372372
subOptions |= NL_KnownNonCascadingDependency;
373-
if (options.contains(NameLookupFlags::DynamicLookup))
374-
subOptions |= NL_DynamicLookup;
375373
if (options.contains(NameLookupFlags::IgnoreAccessControl))
376374
subOptions |= NL_IgnoreAccessControl;
377375

lib/Sema/TypeCheckPattern.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,7 @@ lookupEnumMemberElement(TypeChecker &TC, DeclContext *DC, Type ty,
132132

133133
// Look up the case inside the enum.
134134
// FIXME: We should be able to tell if this is a private lookup.
135-
NameLookupOptions lookupOptions
136-
= defaultMemberLookupOptions - NameLookupFlags::DynamicLookup;
135+
NameLookupOptions lookupOptions = defaultMemberLookupOptions;
137136
LookupResult foundElements = TC.lookupMember(DC, ty, name, lookupOptions);
138137
return filterForEnumElement(TC, DC, UseLoc,
139138
/*unqualifiedLookup=*/false, foundElements);

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,7 @@ inline NameLookupOptions operator|(NameLookupFlags flag1,
309309

310310
/// Default options for member name lookup.
311311
const NameLookupOptions defaultMemberLookupOptions
312-
= NameLookupFlags::DynamicLookup |
313-
NameLookupFlags::ProtocolMembers |
312+
= NameLookupFlags::ProtocolMembers |
314313
NameLookupFlags::PerformConformanceCheck;
315314

316315
/// Default options for constructor lookup.
@@ -489,15 +488,11 @@ enum class TypeResolutionFlags : uint16_t {
489488
/// Whether this type resolution is guaranteed not to affect downstream files.
490489
KnownNonCascadingDependency = 1 << 8,
491490

492-
/// Whether we should resolve only the structure of the resulting
493-
/// type rather than its complete semantic properties.
494-
ResolveStructure = 1 << 9,
495-
496491
/// Whether we are at the direct base of a type expression.
497-
Direct = 1 << 10,
492+
Direct = 1 << 9,
498493

499494
/// Whether we should not produce diagnostics if the type is invalid.
500-
SilenceErrors = 1 << 11,
495+
SilenceErrors = 1 << 10,
501496
};
502497

503498
/// Type resolution contexts that require special handling.

0 commit comments

Comments
 (0)