Skip to content

Commit ffaa358

Browse files
committed
Handle lookup into Builtin with module selector
Lookups like Builtin::Int64 were failing because BuiltinUnit rejected all unqualified lookups. Make it allow unqualified lookups with a module selector.
1 parent 7bf14de commit ffaa358

File tree

16 files changed

+85
-41
lines changed

16 files changed

+85
-41
lines changed

include/swift/AST/LookupKinds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ enum class ModuleLookupFlags : unsigned {
104104
/// If @abi attributes are present, return the decls representing the ABI,
105105
/// not the API.
106106
ABIProviding = 1 << 1,
107+
/// The lookup is qualified by a module selector which has specified this
108+
/// module explicitly.
109+
HasModuleSelector = 1 << 2,
107110
};
108111

109112
} // end namespace swift

include/swift/AST/ModuleNameLookup.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ void simple_display(llvm::raw_ostream &out, ResolutionKind kind);
5353
///
5454
/// \param moduleOrFile The module or file unit to search, including imports.
5555
/// \param name The name to look up.
56+
/// \param hasModuleSelector Whether \p name was originally qualified by a
57+
/// module selector. This information is threaded through to underlying
58+
/// lookup calls; the callee is responsible for actually applying the
59+
/// module selector.
5660
/// \param[out] decls Any found decls will be added to this vector.
5761
/// \param lookupKind Whether this lookup is qualified or unqualified.
5862
/// \param resolutionKind What sort of decl is expected.
@@ -64,8 +68,11 @@ void simple_display(llvm::raw_ostream &out, ResolutionKind kind);
6468
/// \param options name lookup options. Currently only used to communicate the
6569
/// NL_IncludeUsableFromInline option.
6670
void lookupInModule(const DeclContext *moduleOrFile,
67-
DeclName name, SmallVectorImpl<ValueDecl *> &decls,
68-
NLKind lookupKind, ResolutionKind resolutionKind,
71+
DeclName name,
72+
bool hasModuleSelector,
73+
SmallVectorImpl<ValueDecl *> &decls,
74+
NLKind lookupKind,
75+
ResolutionKind resolutionKind,
6976
const DeclContext *moduleScopeContext,
7077
SourceLoc loc, NLOptions options);
7178

include/swift/AST/NameLookupRequests.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,13 +475,13 @@ using QualifiedLookupResult = SmallVector<ValueDecl *, 4>;
475475
class LookupInModuleRequest
476476
: public SimpleRequest<
477477
LookupInModuleRequest,
478-
QualifiedLookupResult(const DeclContext *, DeclName, NLKind,
478+
QualifiedLookupResult(const DeclContext *, DeclName, bool, NLKind,
479479
namelookup::ResolutionKind, const DeclContext *,
480480
NLOptions),
481481
RequestFlags::Uncached | RequestFlags::DependencySink> {
482482
public:
483483
LookupInModuleRequest(
484-
const DeclContext *, DeclName, NLKind,
484+
const DeclContext *, DeclName, bool, NLKind,
485485
namelookup::ResolutionKind, const DeclContext *,
486486
SourceLoc, NLOptions);
487487

@@ -498,6 +498,10 @@ class LookupInModuleRequest
498498
/// \param evaluator The request evaluator.
499499
/// \param moduleOrFile The module or file unit to search, including imports.
500500
/// \param name The name to look up.
501+
/// \param hasModuleSelector Whether \p name was originally qualified by a
502+
/// module selector. This information is threaded through to underlying
503+
/// lookup calls; the callee is responsible for actually applying the
504+
/// module selector.
501505
/// \param lookupKind Whether this lookup is qualified or unqualified.
502506
/// \param resolutionKind What sort of decl is expected.
503507
/// \param moduleScopeContext The top-level context from which the lookup is
@@ -506,7 +510,8 @@ class LookupInModuleRequest
506510
/// \param options Lookup options to apply.
507511
QualifiedLookupResult
508512
evaluate(Evaluator &evaluator, const DeclContext *moduleOrFile, DeclName name,
509-
NLKind lookupKind, namelookup::ResolutionKind resolutionKind,
513+
bool hasModuleSelector, NLKind lookupKind,
514+
namelookup::ResolutionKind resolutionKind,
510515
const DeclContext *moduleScopeContext, NLOptions options) const;
511516

512517
public:

lib/AST/Module.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,6 @@ BuiltinUnit::LookupCache &BuiltinUnit::getCache() const {
104104
void BuiltinUnit::LookupCache::lookupValue(
105105
Identifier Name, NLKind LookupKind, const BuiltinUnit &M,
106106
SmallVectorImpl<ValueDecl*> &Result) {
107-
// Only qualified lookup ever finds anything in the builtin module.
108-
if (LookupKind != NLKind::QualifiedLookup) return;
109-
110107
ValueDecl *&Entry = Cache[Name];
111108
ASTContext &Ctx = M.getParentModule()->getASTContext();
112109
if (!Entry) {
@@ -1073,6 +1070,11 @@ void ModuleDecl::lookupAvailabilityDomains(
10731070
void BuiltinUnit::lookupValue(DeclName name, NLKind lookupKind,
10741071
OptionSet<ModuleLookupFlags> Flags,
10751072
SmallVectorImpl<ValueDecl*> &result) const {
1073+
// Only qualified lookup ever finds anything in the builtin module.
1074+
if (lookupKind != NLKind::QualifiedLookup
1075+
&& !Flags.contains(ModuleLookupFlags::HasModuleSelector))
1076+
return;
1077+
10761078
getCache().lookupValue(name.getBaseIdentifier(), lookupKind, *this, result);
10771079
}
10781080

lib/AST/ModuleNameLookup.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,16 @@ class ModuleNameLookup {
6666
/// \param moduleScopeContext The top-level context from which the lookup is
6767
/// being performed, for checking access. This must be either a
6868
/// FileUnit or a Module.
69+
/// \param hasModuleSelector Whether \p name was originally qualified by a
70+
/// module selector. This information is threaded through to underlying
71+
/// lookup calls; the callee is responsible for actually applying the
72+
/// module selector.
6973
/// \param options Lookup options to apply.
7074
void lookupInModule(SmallVectorImpl<ValueDecl *> &decls,
7175
const DeclContext *moduleOrFile,
7276
ImportPath::Access accessPath,
7377
const DeclContext *moduleScopeContext,
78+
bool hasModuleSelector,
7479
NLOptions options);
7580
};
7681

@@ -173,6 +178,7 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
173178
const DeclContext *moduleOrFile,
174179
ImportPath::Access accessPath,
175180
const DeclContext *moduleScopeContext,
181+
bool hasModuleSelector,
176182
NLOptions options) {
177183
assert(moduleOrFile->isModuleScopeContext());
178184

@@ -189,7 +195,7 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
189195
selfOverlay = true;
190196
else
191197
lookupInModule(decls, overlay, accessPath, moduleScopeContext,
192-
options);
198+
hasModuleSelector, options);
193199
}
194200
// FIXME: This may not work gracefully if more than one of these lookups
195201
// finds something.
@@ -228,6 +234,8 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
228234
currentModuleLookupFlags |= ModuleLookupFlags::ExcludeMacroExpansions;
229235
if (options & NL_ABIProviding)
230236
currentModuleLookupFlags |= ModuleLookupFlags::ABIProviding;
237+
if (hasModuleSelector)
238+
currentModuleLookupFlags |= ModuleLookupFlags::HasModuleSelector;
231239

232240
// Do the lookup into the current module.
233241
auto *module = moduleOrFile->getParentModule();
@@ -255,6 +263,7 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
255263
OptionSet<ModuleLookupFlags> importedModuleLookupFlags = {};
256264
if (options & NL_ABIProviding)
257265
currentModuleLookupFlags |= ModuleLookupFlags::ABIProviding;
266+
// Do not propagate HasModuleSelector here; the selector wasn't specific.
258267

259268
auto visitImport = [&](ImportedModule import,
260269
const DeclContext *moduleScopeContext) {
@@ -357,27 +366,29 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
357366
QualifiedLookupResult
358367
LookupInModuleRequest::evaluate(
359368
Evaluator &evaluator, const DeclContext *moduleOrFile, DeclName name,
360-
NLKind lookupKind, ResolutionKind resolutionKind,
369+
bool hasModuleSelector, NLKind lookupKind, ResolutionKind resolutionKind,
361370
const DeclContext *moduleScopeContext, NLOptions options) const {
362371
assert(moduleScopeContext->isModuleScopeContext());
363372

364373
QualifiedLookupResult decls;
365374
LookupByName lookup(moduleOrFile->getASTContext(), resolutionKind,
366375
name, lookupKind);
367-
lookup.lookupInModule(decls, moduleOrFile, {}, moduleScopeContext, options);
376+
lookup.lookupInModule(decls, moduleOrFile, {}, moduleScopeContext,
377+
hasModuleSelector, options);
368378
return decls;
369379
}
370380

371381
void namelookup::lookupInModule(const DeclContext *moduleOrFile,
372382
DeclName name,
383+
bool hasModuleSelector,
373384
SmallVectorImpl<ValueDecl *> &decls,
374385
NLKind lookupKind,
375386
ResolutionKind resolutionKind,
376387
const DeclContext *moduleScopeContext,
377388
SourceLoc loc, NLOptions options) {
378389
auto &ctx = moduleOrFile->getASTContext();
379-
LookupInModuleRequest req(moduleOrFile, name, lookupKind, resolutionKind,
380-
moduleScopeContext, loc, options);
390+
LookupInModuleRequest req(moduleOrFile, name, hasModuleSelector, lookupKind,
391+
resolutionKind, moduleScopeContext, loc, options);
381392
auto results = evaluateOrDefault(ctx.evaluator, req, {});
382393
decls.append(results.begin(), results.end());
383394
}
@@ -393,6 +404,7 @@ void namelookup::lookupVisibleDeclsInModule(
393404
auto &ctx = moduleOrFile->getASTContext();
394405
LookupVisibleDecls lookup(ctx, resolutionKind, lookupKind);
395406
lookup.lookupInModule(decls, moduleOrFile, accessPath, moduleScopeContext,
407+
/*hasModuleSelector=*/false,
396408
NL_QualifiedDefault);
397409
}
398410

lib/AST/NameLookup.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ bool swift::removeOutOfModuleDecls(SmallVectorImpl<ValueDecl*> &decls,
373373
// We'd need a new ResolutionKind.
374374
// FIXME: How can we diagnose this?
375375
ModuleDecl *visibleFrom = ctx.getLoadedModule(moduleSelector);
376+
if (!visibleFrom && moduleSelector == ctx.TheBuiltinModule->getName())
377+
visibleFrom = ctx.TheBuiltinModule;
376378
if (!visibleFrom) {
377379
LLVM_DEBUG(llvm::dbgs() << "no module " << moduleSelector << "\n");
378380
bool clearedAny = !decls.empty();
@@ -2860,8 +2862,9 @@ ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
28602862
: ResolutionKind::Overloadable);
28612863
auto topLevelScope = DC->getModuleScopeContext();
28622864
if (module == topLevelScope->getParentModule()) {
2863-
lookupInModule(module, member.getFullName(), decls, NLKind::QualifiedLookup,
2864-
kind, topLevelScope, SourceLoc(), options);
2865+
lookupInModule(module, member.getFullName(), member.hasModuleSelector(),
2866+
decls, NLKind::QualifiedLookup, kind, topLevelScope,
2867+
SourceLoc(), options);
28652868
} else {
28662869
// Note: This is a lookup into another module. Unless we're compiling
28672870
// multiple modules at once, or if the other module re-exports this one,
@@ -2876,8 +2879,8 @@ ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
28762879
[&](ImportPath::Access accessPath) {
28772880
return accessPath.matches(member.getFullName());
28782881
})) {
2879-
lookupInModule(module, member.getFullName(), decls,
2880-
NLKind::QualifiedLookup, kind, topLevelScope,
2882+
lookupInModule(module, member.getFullName(), member.hasModuleSelector(),
2883+
decls, NLKind::QualifiedLookup, kind, topLevelScope,
28812884
SourceLoc(), options);
28822885
}
28832886
}

lib/AST/NameLookupRequests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,12 +631,12 @@ UnqualifiedLookupRequest::UnqualifiedLookupRequest(
631631
) : SimpleRequest(contextualizeOptions(descriptor)) { }
632632

633633
LookupInModuleRequest::LookupInModuleRequest(
634-
const DeclContext *moduleOrFile, DeclName name, NLKind lookupKind,
635-
namelookup::ResolutionKind resolutionKind,
634+
const DeclContext *moduleOrFile, DeclName name, bool hasModuleSelector,
635+
NLKind lookupKind, namelookup::ResolutionKind resolutionKind,
636636
const DeclContext *moduleScopeContext,
637637
SourceLoc loc, NLOptions options
638-
) : SimpleRequest(moduleOrFile, name, lookupKind, resolutionKind,
639-
moduleScopeContext,
638+
) : SimpleRequest(moduleOrFile, name, hasModuleSelector, lookupKind,
639+
resolutionKind, moduleScopeContext,
640640
contextualizeOptions(moduleOrFile, loc, options)) { }
641641

642642
ModuleQualifiedLookupRequest::ModuleQualifiedLookupRequest(

lib/AST/UnqualifiedLookup.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -481,12 +481,15 @@ void UnqualifiedLookupFactory::addImportedResults(const DeclContext *const dc) {
481481
: isOriginallyMacroLookup ? ResolutionKind::MacrosOnly
482482
: ResolutionKind::Overloadable;
483483
auto moduleToLookIn = dc;
484-
if (Name.hasModuleSelector())
484+
if (Name.hasModuleSelector()) {
485485
// FIXME: Should we look this up relative to dc?
486486
// We'd need a new ResolutionKind.
487-
moduleToLookIn =
488-
dc->getASTContext().getLoadedModule(Name.getModuleSelector());
489-
487+
auto moduleName = Name.getModuleSelector();
488+
moduleToLookIn = dc->getASTContext().getLoadedModule(moduleName);
489+
if (!moduleToLookIn && moduleName == Ctx.TheBuiltinModule->getName())
490+
moduleToLookIn = Ctx.TheBuiltinModule;
491+
}
492+
490493
// If we didn't find the module, it obviously can't have any results.
491494
if (!moduleToLookIn)
492495
return;
@@ -501,9 +504,9 @@ void UnqualifiedLookupFactory::addImportedResults(const DeclContext *const dc) {
501504
if (options.contains(Flags::IgnoreAccessControl))
502505
nlOptions |= NL_IgnoreAccessControl;
503506

504-
lookupInModule(moduleToLookIn, Name.getFullName(), CurModuleResults,
505-
NLKind::UnqualifiedLookup, resolutionKind, dc,
506-
Loc, nlOptions);
507+
lookupInModule(moduleToLookIn, Name.getFullName(), Name.hasModuleSelector(),
508+
CurModuleResults, NLKind::UnqualifiedLookup, resolutionKind,
509+
dc, Loc, nlOptions);
507510

508511
if (dc->isInSwiftinterface() &&
509512
!dc->getASTContext().LangOpts.FormalCxxInteropMode) {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8130,9 +8130,10 @@ importer::getValueDeclsForName(NominalTypeDecl *decl, StringRef name) {
81308130
// There is no Clang module for this declaration, so perform lookup from
81318131
// the main module. This will find declarations from the bridging header.
81328132
namelookup::lookupInModule(
8133-
ctx.MainModule, ctx.getIdentifier(name), results,
8134-
NLKind::UnqualifiedLookup, namelookup::ResolutionKind::Overloadable,
8135-
ctx.MainModule, SourceLoc(), NL_UnqualifiedDefault);
8133+
ctx.MainModule, ctx.getIdentifier(name), /*hasModuleSelector=*/false,
8134+
results, NLKind::UnqualifiedLookup,
8135+
namelookup::ResolutionKind::Overloadable, ctx.MainModule, SourceLoc(),
8136+
NL_UnqualifiedDefault);
81368137

81378138
// Filter out any declarations that didn't come from Clang.
81388139
auto newEnd =

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ diagnoseIfModuleImportsShadowingDecl(ModuleInterfaceOptions const &Opts,
209209
using namespace namelookup;
210210

211211
SmallVector<ValueDecl *, 4> decls;
212-
lookupInModule(importedModule, importingModule->getName(), decls,
212+
lookupInModule(importedModule, importingModule->getName(),
213+
/*hasModuleSelector=*/false, decls,
213214
NLKind::UnqualifiedLookup, ResolutionKind::TypesOnly,
214215
importedModule, SourceLoc(),
215216
NL_UnqualifiedDefault | NL_IncludeUsableFromInline);

0 commit comments

Comments
 (0)