Skip to content

Add Qualified Lookup Requests #28816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/swift/AST/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,11 @@ inline bool DeclContext::isModuleScopeContext() const {
return isModuleContext();
}

/// Extract the source location from the given module declaration.
inline SourceLoc extractNearestSourceLoc(const ModuleDecl *mod) {
return extractNearestSourceLoc(static_cast<const Decl *>(mod));
}

} // end namespace swift

namespace llvm {
Expand Down
39 changes: 39 additions & 0 deletions include/swift/AST/NameLookupRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,45 @@ class AnyObjectLookupRequest
NLOptions options) const;
};

class ModuleQualifiedLookupRequest
: public SimpleRequest<ModuleQualifiedLookupRequest,
QualifiedLookupResult(const DeclContext *,
ModuleDecl *, DeclNameRef,
NLOptions),
CacheKind::Uncached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<QualifiedLookupResult> evaluate(Evaluator &evaluator,
const DeclContext *DC,
ModuleDecl *mod, DeclNameRef name,
NLOptions opts) const;
};

class QualifiedLookupRequest
: public SimpleRequest<QualifiedLookupRequest,
QualifiedLookupResult(const DeclContext *,
SmallVector<NominalTypeDecl *, 4>,
DeclNameRef, NLOptions),
CacheKind::Uncached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<QualifiedLookupResult>
evaluate(Evaluator &evaluator, const DeclContext *DC,
SmallVector<NominalTypeDecl *, 4> decls,
DeclNameRef name,
NLOptions opts) const;
};

#define SWIFT_TYPEID_ZONE NameLookup
#define SWIFT_TYPEID_HEADER "swift/AST/NameLookupTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
Expand Down
25 changes: 17 additions & 8 deletions include/swift/AST/NameLookupTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
//
//===----------------------------------------------------------------------===//

SWIFT_REQUEST(NameLookup, AnyObjectLookupRequest,
QualifiedLookupResult(const DeclContext *, DeclName, NLOptions),
Uncached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, CustomAttrNominalRequest,
NominalTypeDecl *(CustomAttr *, DeclContext *), Cached,
NoLocationInfo)
Expand All @@ -34,6 +37,20 @@ SWIFT_REQUEST(NameLookup, InheritedDeclsReferencedRequest,
DirectlyReferencedTypeDecls(
llvm::PointerUnion<TypeDecl *, ExtensionDecl *>, unsigned),
Uncached, HasNearestLocation)
SWIFT_REQUEST(NameLookup, LookupInModuleRequest,
QualifiedLookupResult(const DeclContext *, DeclName, NLKind,
namelookup::ResolutionKind,
const DeclContext *),
Uncached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, ModuleQualifiedLookupRequest,
QualifiedLookupResult(
const DeclContext *, ModuleDecl *, DeclNameRef, NLOptions),
Uncached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, QualifiedLookupRequest,
QualifiedLookupResult(
const DeclContext *, SmallVector<NominalTypeDecl *, 4>,
DeclNameRef, NLOptions),
Uncached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, SelfBoundsFromWhereClauseRequest,
SelfBounds(llvm::PointerUnion<TypeDecl *, ExtensionDecl *>),
Uncached, NoLocationInfo)
Expand All @@ -48,11 +65,3 @@ SWIFT_REQUEST(NameLookup, UnderlyingTypeDeclsReferencedRequest,
SWIFT_REQUEST(NameLookup, UnqualifiedLookupRequest,
LookupResult(UnqualifiedLookupDescriptor), Uncached,
NoLocationInfo)
SWIFT_REQUEST(NameLookup, LookupInModuleRequest,
QualifiedLookupResult(const DeclContext *, DeclName, NLKind,
namelookup::ResolutionKind,
const DeclContext *),
Uncached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, AnyObjectLookupRequest,
QualifiedLookupResult(const DeclContext *, DeclName, NLOptions),
Uncached, NoLocationInfo)
6 changes: 0 additions & 6 deletions include/swift/Basic/Statistics.def
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,6 @@ FRONTEND_STATISTIC(AST, NumPrefixOperators)
/// Number of precedence groups in the AST context.
FRONTEND_STATISTIC(AST, NumPrecedenceGroups)

/// Number of qualified lookups into a nominal type.
FRONTEND_STATISTIC(AST, NumLookupQualifiedInNominal)

/// Number of qualified lookups into a module.
FRONTEND_STATISTIC(AST, NumLookupQualifiedInModule)

/// Number of local lookups into a module.
FRONTEND_STATISTIC(AST, NumModuleLookupValue)

Expand Down
65 changes: 40 additions & 25 deletions lib/AST/NameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1587,17 +1587,24 @@ bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
DeclNameRef member,
NLOptions options,
SmallVectorImpl<ValueDecl *> &decls) const {
using namespace namelookup;
assert(decls.empty() && "additive lookup not supported");
QualifiedLookupRequest req{this, {typeDecls.begin(), typeDecls.end()},
member, options};
decls = evaluateOrDefault(getASTContext().evaluator, req, {});
return !decls.empty();
}

auto *stats = getASTContext().Stats;
if (stats)
stats->getFrontendCounters().NumLookupQualifiedInNominal++;
llvm::Expected<QualifiedLookupResult>
QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
SmallVector<NominalTypeDecl *, 4> typeDecls,
DeclNameRef member, NLOptions options) const {
using namespace namelookup;
QualifiedLookupResult decls;

// Configure lookup and dig out the tracker.
ReferencedNameTracker *tracker = nullptr;
bool isLookupCascading;
configureLookup(this, options, tracker, isLookupCascading);
configureLookup(DC, options, tracker, isLookupCascading);

// Tracking for the nominal types we'll visit.
SmallVector<NominalTypeDecl *, 4> stack;
Expand Down Expand Up @@ -1645,8 +1652,7 @@ bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(decl))
continue;

if (isAcceptableLookupResult(this, options, decl,
onlyCompleteObjectInits))
if (isAcceptableLookupResult(DC, options, decl, onlyCompleteObjectInits))
decls.push_back(decl);
}

Expand Down Expand Up @@ -1706,34 +1712,40 @@ bool DeclContext::lookupQualified(ArrayRef<NominalTypeDecl *> typeDecls,
}
}

pruneLookupResultSet(this, options, decls);
if (auto *debugClient = this->getParentModule()->getDebugClient()) {
debugClient->finishLookupInNominals(this, typeDecls, member.getFullName(),
pruneLookupResultSet(DC, options, decls);
if (auto *debugClient = DC->getParentModule()->getDebugClient()) {
debugClient->finishLookupInNominals(DC, typeDecls, member.getFullName(),
options, decls);
}
// We're done. Report success/failure.
return !decls.empty();

return decls;
}

bool DeclContext::lookupQualified(ModuleDecl *module, DeclNameRef member,
NLOptions options,
SmallVectorImpl<ValueDecl *> &decls) const {
using namespace namelookup;
assert(decls.empty() && "additive lookup not supported");
ModuleQualifiedLookupRequest req{this, module, member, options};
decls = evaluateOrDefault(getASTContext().evaluator, req, {});
return !decls.empty();
}

auto &ctx = getASTContext();
auto *stats = ctx.Stats;
if (stats)
stats->getFrontendCounters().NumLookupQualifiedInModule++;
llvm::Expected<QualifiedLookupResult>
ModuleQualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
ModuleDecl *module, DeclNameRef member,
NLOptions options) const {
using namespace namelookup;
QualifiedLookupResult decls;

// Configure lookup and dig out the tracker.
ReferencedNameTracker *tracker = nullptr;
bool isLookupCascading;
configureLookup(this, options, tracker, isLookupCascading);
configureLookup(DC, options, tracker, isLookupCascading);

auto kind = (options & NL_OnlyTypes
? ResolutionKind::TypesOnly
: ResolutionKind::Overloadable);
auto topLevelScope = getModuleScopeContext();
auto topLevelScope = DC->getModuleScopeContext();
if (module == topLevelScope->getParentModule()) {
if (tracker) {
recordLookupOfTopLevelName(topLevelScope, member.getFullName(),
Expand All @@ -1748,6 +1760,7 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclNameRef member,
// anything in this one.

// Perform the lookup in all imports of this module.
auto &ctx = DC->getASTContext();
auto accessPaths = ctx.getImportCache().getAllVisibleAccessPaths(
module, topLevelScope);
if (llvm::any_of(accessPaths,
Expand All @@ -1760,14 +1773,14 @@ bool DeclContext::lookupQualified(ModuleDecl *module, DeclNameRef member,
}
}

pruneLookupResultSet(this, options, decls);
pruneLookupResultSet(DC, options, decls);

if (auto *debugClient = this->getParentModule()->getDebugClient()) {
debugClient->finishLookupInModule(this, module, member.getFullName(),
if (auto *debugClient = DC->getParentModule()->getDebugClient()) {
debugClient->finishLookupInModule(DC, module, member.getFullName(),
options, decls);
}
// We're done. Report success/failure.
return !decls.empty();

return decls;
}

llvm::Expected<QualifiedLookupResult>
Expand Down Expand Up @@ -1997,7 +2010,9 @@ directReferencesForQualifiedTypeLookup(Evaluator &evaluator,
auto innerOptions = options;
innerOptions &= ~NL_RemoveOverridden;
innerOptions &= ~NL_RemoveNonVisible;
dc->lookupQualified(module, name, innerOptions, members);
SmallVector<ValueDecl *, 4> moduleMembers;
dc->lookupQualified(module, name, innerOptions, moduleMembers);
members.append(moduleMembers.begin(), moduleMembers.end());
}

addResults(members);
Expand Down
2 changes: 1 addition & 1 deletion test/decl/circularity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class C4 {
required init(x: Int) {}
}

class D4 : C4, P1 { // expected-note {{through reference here}}
class D4 : C4, P1 { // expected-note 2 {{through reference here}}
required init(x: X) { // expected-error {{circular reference}}
// expected-note@-1 2{{through reference here}}
super.init(x: x)
Expand Down
9 changes: 5 additions & 4 deletions test/decl/class/circular_inheritance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
// Check that we produced superclass type requests.
// RUN: %{python} %utils/process-stats-dir.py --evaluate 'SuperclassTypeRequest == 18' %t/stats-dir

class Left // expected-error {{circular reference}}
class Left // expected-error {{circular reference}} expected-note {{through reference here}}
: Right.Hand { // expected-note {{through reference here}}
class Hand {}
}

class Right // expected-note {{through reference here}}
class Right // expected-note 2 {{through reference here}}
: Left.Hand { // expected-note {{through reference here}}
class Hand {}
}
Expand All @@ -35,13 +35,13 @@ class Outer {
class Inner : Outer {}
}

class Outer2 // expected-error {{circular reference}}
class Outer2 // expected-error {{circular reference}} expected-note {{through reference here}}
: Outer2.Inner { // expected-note {{through reference here}}

class Inner {}
}

class Outer3 // expected-error {{circular reference}}
class Outer3 // expected-error {{circular reference}} expected-note {{through reference here}}
: Outer3.Inner<Int> { // expected-note {{through reference here}}
class Inner<T> {}
}
Expand Down Expand Up @@ -79,6 +79,7 @@ class WithDesignatedInit : WithDesignatedInit {
// expected-error@-1 {{'WithDesignatedInit' inherits from itself}}
// expected-error@-2 {{circular reference}}
// expected-note@-3 {{through reference here}}
// expected-note@-4 2 {{through reference here}}

init(x: Int) {} // expected-error {{circular reference}}
}