Skip to content

Commit 1dfc0bf

Browse files
committed
Handle module selectors in qualified lookup
1 parent e662993 commit 1dfc0bf

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

include/swift/AST/NameLookup.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,14 @@ class UsableFilteringDeclConsumer final : public VisibleDeclConsumer {
486486
/// \returns true if any declarations were removed, false otherwise.
487487
bool removeOverriddenDecls(SmallVectorImpl<ValueDecl*> &decls);
488488

489+
/// Remove any declarations in the given set that do not match the
490+
/// module selector, if it is not empty.
491+
///
492+
/// \returns true if any declarations were removed, false otherwise.
493+
bool removeOutOfModuleDecls(SmallVectorImpl<ValueDecl*> &decls,
494+
Identifier moduleSelector,
495+
const DeclContext *dc);
496+
489497
/// Remove any declarations in the given set that are shadowed by
490498
/// other declarations in that set.
491499
///
@@ -561,6 +569,7 @@ void tryExtractDirectlyReferencedNominalTypes(
561569
/// Once name lookup has gathered a set of results, perform any necessary
562570
/// steps to prune the result set before returning it to the caller.
563571
void pruneLookupResultSet(const DeclContext *dc, NLOptions options,
572+
Identifier moduleSelector,
564573
SmallVectorImpl<ValueDecl *> &decls);
565574

566575
/// Do nothing if debugClient is null.

lib/AST/NameLookup.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,43 @@ enum class ConstructorComparison {
361361
Better,
362362
};
363363

364+
bool swift::removeOutOfModuleDecls(SmallVectorImpl<ValueDecl*> &decls,
365+
Identifier moduleSelector,
366+
const DeclContext *dc) {
367+
if (moduleSelector.empty())
368+
return false;
369+
370+
ASTContext &ctx = dc->getASTContext();
371+
372+
// FIXME: Should we look this up relative to dc?
373+
// We'd need a new ResolutionKind.
374+
// FIXME: How can we diagnose this?
375+
ModuleDecl *visibleFrom = ctx.getLoadedModule(moduleSelector);
376+
if (!visibleFrom) {
377+
LLVM_DEBUG(llvm::dbgs() << "no module " << moduleSelector << "\n");
378+
bool clearedAny = !decls.empty();
379+
decls.clear();
380+
return clearedAny;
381+
}
382+
383+
size_t initialCount = decls.size();
384+
decls.erase(
385+
std::remove_if(decls.begin(), decls.end(), [&](ValueDecl *decl) -> bool {
386+
bool inScope = ctx.getImportCache().isImportedBy(decl->getModuleContext(),
387+
visibleFrom);
388+
389+
LLVM_DEBUG(decl->dumpRef(llvm::dbgs()));
390+
LLVM_DEBUG(llvm::dbgs() << ": " << decl->getModuleContext()->getName()
391+
<< (inScope ? " is " : " is NOT ")
392+
<< "selected by " << visibleFrom->getName()
393+
<< "\n");
394+
395+
return !inScope;
396+
}),
397+
decls.end());
398+
return initialCount != decls.size();
399+
}
400+
364401
/// Determines whether \p ctor1 is a "better" initializer than \p ctor2.
365402
static ConstructorComparison compareConstructors(ConstructorDecl *ctor1,
366403
ConstructorDecl *ctor2,
@@ -2471,14 +2508,17 @@ bool namelookup::isInABIAttr(SourceFile *sourceFile, SourceLoc loc) {
24712508
}
24722509

24732510
void namelookup::pruneLookupResultSet(const DeclContext *dc, NLOptions options,
2511+
Identifier moduleSelector,
24742512
SmallVectorImpl<ValueDecl *> &decls) {
24752513
// If we're supposed to remove overridden declarations, do so now.
24762514
if (options & NL_RemoveOverridden)
24772515
removeOverriddenDecls(decls);
24782516

24792517
// If we're supposed to remove shadowed/hidden declarations, do so now.
2480-
if (options & NL_RemoveNonVisible)
2518+
if (options & NL_RemoveNonVisible) {
2519+
removeOutOfModuleDecls(decls, moduleSelector, dc);
24812520
removeShadowedDecls(decls, dc);
2521+
}
24822522

24832523
ModuleDecl *M = dc->getParentModule();
24842524
filterForDiscriminator(decls, M->getDebugClient());
@@ -2790,7 +2830,7 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
27902830
}
27912831
}
27922832

2793-
pruneLookupResultSet(DC, options, decls);
2833+
pruneLookupResultSet(DC, options, member.getModuleSelector(), decls);
27942834
if (auto *debugClient = DC->getParentModule()->getDebugClient()) {
27952835
debugClient->finishLookupInNominals(DC, typeDecls, member.getFullName(),
27962836
options, decls);
@@ -2842,7 +2882,7 @@ ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
28422882
}
28432883
}
28442884

2845-
pruneLookupResultSet(DC, options, decls);
2885+
pruneLookupResultSet(DC, options, member.getModuleSelector(), decls);
28462886

28472887
if (auto *debugClient = DC->getParentModule()->getDebugClient()) {
28482888
debugClient->finishLookupInModule(DC, module, member.getFullName(),
@@ -2910,7 +2950,7 @@ AnyObjectLookupRequest::evaluate(Evaluator &evaluator, const DeclContext *dc,
29102950
decls.push_back(decl);
29112951
}
29122952

2913-
pruneLookupResultSet(dc, options, decls);
2953+
pruneLookupResultSet(dc, options, member.getModuleSelector(), decls);
29142954
if (auto *debugClient = dc->getParentModule()->getDebugClient()) {
29152955
debugClient->finishLookupInAnyObject(dc, member.getFullName(), options,
29162956
decls);

test/NameLookup/module_selector.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extension A: @retroactive Swift::Equatable {
4040
let fn: (Swift::Int, Swift::Int) -> Swift::Int = (Swift::+)
4141

4242
let magnitude: Int.Swift::Magnitude = main::magnitude
43+
// expected-error@-1 {{cannot convert value of type 'Never' to specified type 'Int.Magnitude' (aka 'UInt')}}
4344

4445
_ = (fn, magnitude)
4546

@@ -78,18 +79,21 @@ extension B: @retroactive main::Equatable {
7879
// @_derivative(of:)
7980

8081
@_dynamicReplacement(for: main::negate())
82+
// FIXME improve: expected-error@-1 {{replaced function 'main::negate()' could not be found}}
8183

8284
mutating func myNegate() {
8385
let fn: (main::Int, main::Int) -> main::Int =
8486
(main::+)
8587

8688
let magnitude: Int.main::Magnitude = main::magnitude
89+
// FIXME improve: expected-error@-1 {{'main::Magnitude' is not a member type of struct 'Swift.Int'}}
8790

8891
_ = (fn, magnitude)
8992

9093
if main::Bool.main::random() {
9194

9295
main::negate()
96+
// FIXME improve: expected-error@-1 {{cannot find 'main::negate' in scope}}
9397
}
9498
else {
9599
self = main::B(value: .main::min)
@@ -130,6 +134,7 @@ extension C: @retroactive ModuleSelectorTestingKit::Equatable {
130134
(ModuleSelectorTestingKit::+)
131135

132136
let magnitude: Int.ModuleSelectorTestingKit::Magnitude = ModuleSelectorTestingKit::magnitude
137+
// FIXME improve: expected-error@-1 {{'ModuleSelectorTestingKit::Magnitude' is not a member type of struct 'Swift.Int'}}
133138

134139
_ = (fn, magnitude)
135140

@@ -169,19 +174,22 @@ extension D: @retroactive Swift::Equatable {
169174
// @_derivative(of:)
170175

171176
@_dynamicReplacement(for: Swift::negate())
177+
// FIXME improve: expected-error@-1 {{replaced function 'Swift::negate()' could not be found}}
172178

173179
mutating func myNegate() {
174180

175181
let fn: (Swift::Int, Swift::Int) -> Swift::Int =
176182
(Swift::+)
177183

178184
let magnitude: Int.Swift::Magnitude = Swift::magnitude
185+
// expected-error@-1 {{cannot convert value of type 'Never' to specified type 'Int.Magnitude' (aka 'UInt')}}
179186

180187
_ = (fn, magnitude)
181188

182189
if Swift::Bool.Swift::random() {
183190

184191
Swift::negate()
192+
// FIXME improve: expected-error@-1 {{cannot find 'Swift::negate' in scope}}
185193
}
186194
else {
187195
self = Swift::D(value: .Swift::min)

0 commit comments

Comments
 (0)