Skip to content

Commit f0f2878

Browse files
authored
Merge pull request #33976 from slavapestov/remove-astscope-starting-dc-hack
Remove ASTScope starting DeclContext hack
2 parents 50735fc + 09bb3c0 commit f0f2878

File tree

8 files changed

+39
-169
lines changed

8 files changed

+39
-169
lines changed

include/swift/AST/ASTScope.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,7 @@ class ASTScopeImpl {
411411

412412
/// Entry point into ASTScopeImpl-land for lookups
413413
static llvm::SmallVector<const ASTScopeImpl *, 0>
414-
unqualifiedLookup(SourceFile *, DeclNameRef, SourceLoc,
415-
const DeclContext *startingContext, DeclConsumer);
414+
unqualifiedLookup(SourceFile *, DeclNameRef, SourceLoc, DeclConsumer);
416415

417416
/// Entry point into ASTScopeImpl-land for labeled statement lookups.
418417
static llvm::SmallVector<LabeledStmt *, 4>
@@ -429,11 +428,7 @@ class ASTScopeImpl {
429428
private:
430429
static const ASTScopeImpl *findStartingScopeForLookup(SourceFile *,
431430
const DeclNameRef name,
432-
const SourceLoc where,
433-
const DeclContext *ctx);
434-
435-
protected:
436-
virtual bool doesContextMatchStartingContext(const DeclContext *) const;
431+
const SourceLoc where);
437432

438433
protected:
439434
/// Not const because may reexpand some scopes.
@@ -1006,7 +1001,6 @@ class GenericParamScope final : public ASTScopeImpl {
10061001
protected:
10071002
bool lookupLocalsOrMembers(ArrayRef<const ASTScopeImpl *>,
10081003
DeclConsumer) const override;
1009-
bool doesContextMatchStartingContext(const DeclContext *) const override;
10101004
Optional<bool>
10111005
resolveIsCascadingUseForThisScope(Optional<bool>) const override;
10121006
};
@@ -1622,7 +1616,6 @@ class DifferentiableAttributeScope final : public ASTScopeImpl {
16221616
ASTScopeImpl *expandSpecifically(ScopeCreator &) override;
16231617
bool lookupLocalsOrMembers(ArrayRef<const ASTScopeImpl *>,
16241618
DeclConsumer) const override;
1625-
bool doesContextMatchStartingContext(const DeclContext *) const override;
16261619
};
16271620

16281621
class SubscriptDeclScope final : public ASTScopeImpl {

include/swift/AST/NameLookup.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,6 @@ class ASTScope {
691691
/// \return the scopes traversed
692692
static llvm::SmallVector<const ast_scope::ASTScopeImpl *, 0>
693693
unqualifiedLookup(SourceFile *, DeclNameRef, SourceLoc,
694-
const DeclContext *startingContext,
695694
namelookup::AbstractASTScopeDeclConsumer &);
696695

697696
static Optional<bool>

lib/AST/ASTScope.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@ using namespace ast_scope;
4040

4141
llvm::SmallVector<const ASTScopeImpl *, 0> ASTScope::unqualifiedLookup(
4242
SourceFile *SF, DeclNameRef name, SourceLoc loc,
43-
const DeclContext *startingContext,
4443
namelookup::AbstractASTScopeDeclConsumer &consumer) {
4544
if (auto *s = SF->getASTContext().Stats)
4645
++s->getFrontendCounters().NumASTScopeLookups;
47-
return ASTScopeImpl::unqualifiedLookup(SF, name, loc, startingContext,
48-
consumer);
46+
return ASTScopeImpl::unqualifiedLookup(SF, name, loc, consumer);
4947
}
5048

5149
Optional<bool> ASTScope::computeIsCascadingUse(

lib/AST/ASTScopeLookup.cpp

Lines changed: 4 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,19 @@ using namespace swift;
3535
using namespace namelookup;
3636
using namespace ast_scope;
3737

38-
static bool isLocWithinAnInactiveClause(const SourceLoc loc, SourceFile *SF);
39-
4038
llvm::SmallVector<const ASTScopeImpl *, 0> ASTScopeImpl::unqualifiedLookup(
4139
SourceFile *sourceFile, const DeclNameRef name, const SourceLoc loc,
42-
const DeclContext *const startingContext, DeclConsumer consumer) {
40+
DeclConsumer consumer) {
4341
SmallVector<const ASTScopeImpl *, 0> history;
4442
const auto *start =
45-
findStartingScopeForLookup(sourceFile, name, loc, startingContext);
43+
findStartingScopeForLookup(sourceFile, name, loc);
4644
if (start)
4745
start->lookup(history, nullptr, nullptr, consumer);
4846
return history;
4947
}
5048

5149
const ASTScopeImpl *ASTScopeImpl::findStartingScopeForLookup(
52-
SourceFile *sourceFile, const DeclNameRef name, const SourceLoc loc,
53-
const DeclContext *const startingContext) {
54-
// At present, use legacy code in unqualifiedLookup.cpp to handle module-level
55-
// lookups
56-
// TODO: implement module scope someday
57-
if (startingContext->getContextKind() == DeclContextKind::Module)
58-
return nullptr;
59-
50+
SourceFile *sourceFile, const DeclNameRef name, const SourceLoc loc) {
6051
auto *const fileScope = sourceFile->getScope().impl;
6152
// Parser may have added decls to source file, since previous lookup
6253
if (name.isOperator())
@@ -66,63 +57,7 @@ const ASTScopeImpl *ASTScopeImpl::findStartingScopeForLookup(
6657
ASTScopeAssert(innermost->getWasExpanded(),
6758
"If looking in a scope, it must have been expanded.");
6859

69-
// The legacy lookup code gets passed both a SourceLoc and a starting context.
70-
// However, our ultimate intent is for clients to not have to pass in a
71-
// DeclContext at all, since the SourceLoc should be enough. While we are
72-
// debugging the new ASTScope lookup code, we can catch bugs by comparing the
73-
// DeclContext of the ASTScope found from the desired SourceLoc to the
74-
// DeclContext passed in by the client.
75-
76-
const auto *startingScope = innermost;
77-
for (; startingScope &&
78-
!startingScope->doesContextMatchStartingContext(startingContext);
79-
startingScope = startingScope->getParent().getPtrOrNull()) {
80-
}
81-
// Someday, just use the assertion below. For now, print out lots of info for
82-
// debugging.
83-
if (!startingScope) {
84-
85-
// Be lenient in code completion mode. There are cases where the decl
86-
// context doesn't match with the ASTScope. e.g. dangling attributes.
87-
// FIXME: Create ASTScope tree even for invalid code.
88-
if (innermost &&
89-
startingContext->getASTContext().SourceMgr.hasCodeCompletionBuffer()) {
90-
return innermost;
91-
}
92-
93-
llvm::errs() << "ASTScopeImpl: resorting to startingScope hack, file: "
94-
<< sourceFile->getFilename() << "\n";
95-
// The check is costly, and inactive lookups will end up here, so don't
96-
// do the check unless we can't find the startingScope.
97-
const bool isInInactiveClause =
98-
isLocWithinAnInactiveClause(loc, sourceFile);
99-
if (isInInactiveClause)
100-
llvm::errs() << " because location is within an inactive clause\n";
101-
llvm::errs() << "'";
102-
name.print(llvm::errs());
103-
llvm::errs() << "' ";
104-
llvm::errs() << "loc: ";
105-
loc.print(llvm::errs(), sourceFile->getASTContext().SourceMgr);
106-
llvm::errs() << "\nstarting context:\n ";
107-
startingContext->printContext(llvm::errs());
108-
// llvm::errs() << "\ninnermost: ";
109-
// innermost->dump();
110-
// llvm::errs() << "in: \n";
111-
// fileScope->dump();
112-
llvm::errs() << "\n\n";
113-
114-
// Might distort things
115-
// if (fileScope->crossCheckWithAST())
116-
// llvm::errs() << "Tree creation missed some DeclContexts.\n";
117-
118-
// Crash compilation even if NDEBUG
119-
if (isInInactiveClause)
120-
llvm::report_fatal_error(
121-
"A lookup was attempted into an inactive clause");
122-
}
123-
124-
ASTScopeAssert(startingScope, "ASTScopeImpl: could not find startingScope");
125-
return startingScope;
60+
return innermost;
12661
}
12762

12863
ASTScopeImpl *
@@ -189,53 +124,6 @@ ASTScopeImpl::findChildContaining(SourceLoc loc,
189124
return nullptr;
190125
}
191126

192-
#pragma mark doesContextMatchStartingContext
193-
// Match existing UnqualifiedLookupBehavior
194-
195-
bool ASTScopeImpl::doesContextMatchStartingContext(
196-
const DeclContext *context) const {
197-
// Why are we not checking the loc for this--because already did binary search
198-
// on loc to find the start First, try MY DeclContext
199-
if (auto myDCForL = getDeclContext())
200-
return myDCForL == context;
201-
// If I don't have one, ask my parent.
202-
// (Choose innermost scope with matching loc & context.)
203-
if (auto p = getParent())
204-
return p.get()->doesContextMatchStartingContext(context);
205-
// Topmost scope always has a context, the SourceFile.
206-
ASTScope_unreachable("topmost scope always has a context, the SourceFile");
207-
}
208-
209-
// For a SubscriptDecl with generic parameters, the call tries to do lookups
210-
// with startingContext equal to either the get or set subscript
211-
// AbstractFunctionDecls. Since the generic parameters are in the
212-
// SubscriptDeclScope, and not the AbstractFunctionDecl scopes (after all how
213-
// could one parameter be in two scopes?), GenericParamScope intercepts the
214-
// match query here and tests against the accessor DeclContexts.
215-
bool GenericParamScope::doesContextMatchStartingContext(
216-
const DeclContext *context) const {
217-
if (auto *asd = dyn_cast<AbstractStorageDecl>(holder)) {
218-
for (auto accessor : asd->getAllAccessors()) {
219-
if (up_cast<DeclContext>(accessor) == context)
220-
return true;
221-
}
222-
}
223-
return false;
224-
}
225-
226-
bool DifferentiableAttributeScope::doesContextMatchStartingContext(
227-
const DeclContext *context) const {
228-
// Need special logic to handle case where `attributedDeclaration` is an
229-
// `AbstractStorageDecl` (`SubscriptDecl` or `VarDecl`). The initial starting
230-
// context in `ASTScopeImpl::findStartingScopeForLookup` will be an accessor
231-
// of the `attributedDeclaration`.
232-
if (auto *asd = dyn_cast<AbstractStorageDecl>(attributedDeclaration))
233-
for (auto accessor : asd->getAllAccessors())
234-
if (up_cast<DeclContext>(accessor) == context)
235-
return true;
236-
return false;
237-
}
238-
239127
#pragma mark lookup methods that run once per scope
240128

241129
void ASTScopeImpl::lookup(SmallVectorImpl<const ASTScopeImpl *> &history,
@@ -841,39 +729,6 @@ Optional<bool> PatternEntryInitializerScope::resolveIsCascadingUseForThisScope(
841729
return isCascadingUse;
842730
}
843731

844-
bool isLocWithinAnInactiveClause(const SourceLoc loc, SourceFile *SF) {
845-
class InactiveClauseTester : public ASTWalker {
846-
const SourceLoc loc;
847-
const SourceManager &SM;
848-
849-
public:
850-
bool wasFoundWithinInactiveClause = false;
851-
852-
InactiveClauseTester(const SourceLoc loc, const SourceManager &SM)
853-
: loc(loc), SM(SM) {}
854-
855-
bool walkToDeclPre(Decl *D) override {
856-
if (const auto *ifc = dyn_cast<IfConfigDecl>(D)) {
857-
for (const auto &clause : ifc->getClauses()) {
858-
if (clause.isActive)
859-
continue;
860-
for (const auto &n : clause.Elements) {
861-
SourceRange sr = n.getSourceRange();
862-
if (sr.isValid() && SM.rangeContainsTokenLoc(sr, loc)) {
863-
wasFoundWithinInactiveClause = true;
864-
return false;
865-
}
866-
}
867-
}
868-
}
869-
return ASTWalker::walkToDeclPre(D);
870-
}
871-
};
872-
InactiveClauseTester tester(loc, SF->getASTContext().SourceMgr);
873-
SF->walk(tester);
874-
return tester.wasFoundWithinInactiveClause;
875-
}
876-
877732
#pragma mark isLabeledStmtLookupTerminator implementations
878733
bool ASTScopeImpl::isLabeledStmtLookupTerminator() const {
879734
return true;

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,7 @@ SourceRange ClosureParametersScope::getSourceRangeOfThisASTNode(
456456
if (!omitAssertions)
457457
ASTScopeAssert(closureExpr->getInLoc().isValid(),
458458
"We don't create these if no in loc");
459-
return SourceRange(getStartOfFirstParam(closureExpr),
460-
closureExpr->getInLoc());
459+
return SourceRange(closureExpr->getInLoc(), closureExpr->getEndLoc());
461460
}
462461

463462
SourceRange

lib/AST/NameLookup.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,7 +1946,33 @@ static DirectlyReferencedTypeDecls
19461946
directReferencesForUnqualifiedTypeLookup(DeclNameRef name,
19471947
SourceLoc loc, DeclContext *dc,
19481948
LookupOuterResults lookupOuter) {
1949+
// In a protocol or protocol extension, the 'where' clause can refer to
1950+
// associated types without 'Self' qualification:
1951+
//
1952+
// protocol MyProto where AssocType : Q { ... }
1953+
//
1954+
// extension MyProto where AssocType == Int { ... }
1955+
//
1956+
// For this reason, ASTScope maps source locations inside the 'where'
1957+
// clause to a scope that performs the lookup into the protocol or
1958+
// protocol extension.
1959+
//
1960+
// However, protocol and protocol extensions can also put bounds on 'Self',
1961+
// for example:
1962+
//
1963+
// protocol MyProto where Self : MyClass { ... }
1964+
//
1965+
// We must start searching for 'MyClass' at the top level, otherwise
1966+
// we end up with a cycle, because qualified lookup wants to resolve
1967+
// 'Self' bounds to build the set of declarations to search inside of.
1968+
//
1969+
// To make this work, we handle the top-level lookup case explicitly
1970+
// here, bypassing unqualified lookup and ASTScope altogether.
1971+
if (dc->isModuleScopeContext())
1972+
loc = SourceLoc();
1973+
19491974
DirectlyReferencedTypeDecls results;
1975+
19501976
UnqualifiedLookupOptions options =
19511977
UnqualifiedLookupFlags::TypeLookup |
19521978
UnqualifiedLookupFlags::AllowProtocolMembers;
@@ -1958,8 +1984,8 @@ directReferencesForUnqualifiedTypeLookup(DeclNameRef name,
19581984
auto lookup = evaluateOrDefault(ctx.evaluator,
19591985
UnqualifiedLookupRequest{descriptor}, {});
19601986
for (const auto &result : lookup.allResults()) {
1961-
if (auto typeDecl = dyn_cast<TypeDecl>(result.getValueDecl()))
1962-
results.push_back(typeDecl);
1987+
auto typeDecl = cast<TypeDecl>(result.getValueDecl());
1988+
results.push_back(typeDecl);
19631989
}
19641990

19651991
return results;

lib/AST/UnqualifiedLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ void UnqualifiedLookupFactory::lookInASTScopes() {
544544
#endif
545545

546546
ASTScope::unqualifiedLookup(DC->getParentSourceFile(),
547-
Name, Loc, DC, consumer);
547+
Name, Loc, consumer);
548548
}
549549

550550
bool ASTScopeDeclConsumerForUnqualifiedLookup::consume(

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7289,8 +7289,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
72897289

72907290
auto descriptor = UnqualifiedLookupDescriptor(
72917291
DeclNameRef(param->getName()),
7292-
paramDecl->getDeclContext()->getParentForLookup(),
7293-
paramDecl->getStartLoc(),
7292+
paramDecl->getDeclContext()->getParentSourceFile(),
7293+
SourceLoc(),
72947294
UnqualifiedLookupFlags::KnownPrivate |
72957295
UnqualifiedLookupFlags::TypeLookup);
72967296
auto lookup = evaluateOrDefault(

0 commit comments

Comments
 (0)