Skip to content

Commit 9b851bf

Browse files
committed
ASTScope: Collapse PureFunctionBodyScope and MethodBodyScope
This centralizes some invariants around the 'self' parameter. While all ConstructorDecls and DestructorDecls have a 'self', even if they're invalid because they're not nested inside a type, we don't want to consider this as the base 'self' for lookups. Eg, consider this invalid code: class C { func f() { init() { x } } } The base for the lookup should be f.self, not f.init.self.
1 parent 9c4c959 commit 9b851bf

File tree

6 files changed

+19
-55
lines changed

6 files changed

+19
-55
lines changed

include/swift/AST/ASTScope.h

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,6 @@ class AbstractFunctionBodyScope : public ASTScopeImpl {
11131113
}
11141114
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
11151115
Decl *getDecl() const { return decl; }
1116-
static bool isAMethod(const AbstractFunctionDecl *);
11171116

11181117
NullablePtr<ASTScopeImpl> getParentOfASTAncestorScopesToBeRescued() override;
11191118

@@ -1128,25 +1127,15 @@ class AbstractFunctionBodyScope : public ASTScopeImpl {
11281127
SourceRange sourceRangeForDeferredExpansion() const override;
11291128
};
11301129

1131-
/// Body of methods, functions in types.
1132-
class MethodBodyScope final : public AbstractFunctionBodyScope {
1130+
/// Body of functions and methods.
1131+
class FunctionBodyScope final : public AbstractFunctionBodyScope {
11331132
public:
1134-
MethodBodyScope(AbstractFunctionDecl *e) : AbstractFunctionBodyScope(e) {}
1135-
std::string getClassName() const override;
1136-
bool lookupLocalsOrMembers(ArrayRef<const ASTScopeImpl *>,
1137-
DeclConsumer consumer) const override;
1138-
1139-
Optional<NullablePtr<DeclContext>> computeSelfDCForParent() const override;
1140-
};
1141-
1142-
/// Body of "pure" functions, functions without an implicit "self".
1143-
class PureFunctionBodyScope final : public AbstractFunctionBodyScope {
1144-
public:
1145-
PureFunctionBodyScope(AbstractFunctionDecl *e)
1133+
FunctionBodyScope(AbstractFunctionDecl *e)
11461134
: AbstractFunctionBodyScope(e) {}
11471135
std::string getClassName() const override;
11481136
bool lookupLocalsOrMembers(ArrayRef<const ASTScopeImpl *>,
11491137
DeclConsumer consumer) const override;
1138+
Optional<NullablePtr<DeclContext>> computeSelfDCForParent() const override;
11501139
};
11511140

11521141
class DefaultArgumentInitializerScope final : public ASTScopeImpl {

lib/AST/ASTScope.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,6 @@ Stmt *LabeledConditionalStmtScope::getStmt() const {
118118
return getLabeledConditionalStmt();
119119
}
120120

121-
bool AbstractFunctionBodyScope::isAMethod(
122-
const AbstractFunctionDecl *const afd) {
123-
// What makes this interesting is that a method named "init" which is not
124-
// in a nominal type or extension decl body still gets an implicit self
125-
// parameter (even though the program is illegal).
126-
// So when choosing between creating a MethodBodyScope and a
127-
// PureFunctionBodyScope do we go by the enclosing Decl (i.e.
128-
// "afd->getDeclContext()->isTypeContext()") or by
129-
// "bool(afd->getImplicitSelfDecl())"?
130-
//
131-
// Since the code uses \c getImplicitSelfDecl, use that.
132-
return afd->getImplicitSelfDecl();
133-
}
134-
135121
#pragma mark getLabeledConditionalStmt
136122
LabeledConditionalStmt *IfStmtScope::getLabeledConditionalStmt() const {
137123
return stmt;
@@ -218,8 +204,7 @@ DEFINE_GET_CLASS_NAME(ASTSourceFileScope)
218204
DEFINE_GET_CLASS_NAME(GenericParamScope)
219205
DEFINE_GET_CLASS_NAME(AbstractFunctionDeclScope)
220206
DEFINE_GET_CLASS_NAME(ParameterListScope)
221-
DEFINE_GET_CLASS_NAME(MethodBodyScope)
222-
DEFINE_GET_CLASS_NAME(PureFunctionBodyScope)
207+
DEFINE_GET_CLASS_NAME(FunctionBodyScope)
223208
DEFINE_GET_CLASS_NAME(DefaultArgumentInitializerScope)
224209
DEFINE_GET_CLASS_NAME(AttachedPropertyWrapperScope)
225210
DEFINE_GET_CLASS_NAME(PatternEntryDeclScope)

lib/AST/ASTScopeCreation.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,12 +1416,8 @@ void AbstractFunctionDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
14161416
// We create body scopes when there is no body for source kit to complete
14171417
// erroneous code in bodies.
14181418
if (decl->getBodySourceRange().isValid()) {
1419-
if (AbstractFunctionBodyScope::isAMethod(decl))
1420-
scopeCreator.constructExpandAndInsertUncheckable<MethodBodyScope>(leaf,
1419+
scopeCreator.constructExpandAndInsertUncheckable<FunctionBodyScope>(leaf,
14211420
decl);
1422-
else
1423-
scopeCreator.constructExpandAndInsertUncheckable<PureFunctionBodyScope>(
1424-
leaf, decl);
14251421
}
14261422
}
14271423

lib/AST/ASTScopeLookup.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -335,22 +335,15 @@ bool AbstractFunctionBodyScope::lookupLocalsOrMembers(
335335
return false;
336336
}
337337

338-
bool MethodBodyScope::lookupLocalsOrMembers(
338+
bool FunctionBodyScope::lookupLocalsOrMembers(
339339
ArrayRef<const ASTScopeImpl *> history, DeclConsumer consumer) const {
340-
ASTScopeAssert(isAMethod(decl), "Asking for members of a non-method.");
341340
if (AbstractFunctionBodyScope::lookupLocalsOrMembers(history, consumer))
342341
return true;
343-
return consumer.consume({decl->getImplicitSelfDecl()},
344-
DeclVisibilityKind::FunctionParameter);
345-
}
346342

347-
bool PureFunctionBodyScope::lookupLocalsOrMembers(
348-
ArrayRef<const ASTScopeImpl *> history, DeclConsumer consumer) const {
349-
ASTScopeAssert(
350-
!isAMethod(decl),
351-
"Should have called lookupLocalsOrMembers instead of this function.");
352-
if (AbstractFunctionBodyScope::lookupLocalsOrMembers(history, consumer))
353-
return true;
343+
if (decl->getDeclContext()->isTypeContext()) {
344+
return consumer.consume({decl->getImplicitSelfDecl()},
345+
DeclVisibilityKind::FunctionParameter);
346+
}
354347

355348
// Consider \c var t: T { (did/will/)get/set { ... t }}
356349
// Lookup needs to find t, but if the var is inside of a type the baseDC needs
@@ -361,6 +354,7 @@ bool PureFunctionBodyScope::lookupLocalsOrMembers(
361354
if (consumer.consume({storage}, DeclVisibilityKind::LocalVariable))
362355
return true;
363356
}
357+
364358
return false;
365359
}
366360

@@ -629,8 +623,10 @@ PatternEntryInitializerScope::computeSelfDCForParent() const {
629623
}
630624

631625
Optional<NullablePtr<DeclContext>>
632-
MethodBodyScope::computeSelfDCForParent() const {
633-
return NullablePtr<DeclContext>(decl);
626+
FunctionBodyScope::computeSelfDCForParent() const {
627+
if (decl->getDeclContext()->isTypeContext())
628+
return NullablePtr<DeclContext>(decl);
629+
return None;
634630
}
635631

636632
#pragma mark capturedSelfDC

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,7 @@ LookupResult TypeChecker::lookupUnqualified(DeclContext *dc, DeclNameRef name,
255255
if (!typeDC->isTypeContext()) {
256256
// If we don't have a type context this is an implicit 'self' reference.
257257
if (auto *CE = dyn_cast<ClosureExpr>(typeDC)) {
258-
// If we found the result in a self capture, look through the capture.
259-
assert(CE->getCapturedSelfDecl());
260-
typeDC = found.getValueDecl()->getDeclContext();
258+
typeDC = typeDC->getInnermostTypeContext();
261259
} else {
262260
// Otherwise, we must have the method context.
263261
typeDC = typeDC->getParent();

test/NameLookup/scope_map_top_level.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var i: Int = b.my_identity()
4242
// CHECK-EXPANDED-NEXT: `-LookupParentDiversionScope, [9:1 - 21:28]
4343
// CHECK-EXPANDED-NEXT: |-AbstractFunctionDeclScope {{.*}}, [11:1 - 11:13] 'foo()'
4444
// CHECK-EXPANDED-NEXT: `-ParameterListScope {{.*}}, [11:9 - 11:13]
45-
// CHECK-EXPANDED-NEXT: `-PureFunctionBodyScope {{.*}}, [11:12 - 11:13]
45+
// CHECK-EXPANDED-NEXT: `-FunctionBodyScope {{.*}}, [11:12 - 11:13]
4646
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [11:12 - 11:13]
4747
// CHECK-EXPANDED-NEXT: `-TopLevelCodeScope {{.*}}, [13:1 - 21:28]
4848
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [13:1 - 21:28]
@@ -53,7 +53,7 @@ var i: Int = b.my_identity()
5353
// CHECK-EXPANDED-NEXT: `-ExtensionBodyScope {{.*}}, [17:15 - 19:1]
5454
// CHECK-EXPANDED-NEXT: `-AbstractFunctionDeclScope {{.*}}, [18:3 - 18:43] 'my_identity()'
5555
// CHECK-EXPANDED-NEXT: `-ParameterListScope {{.*}}, [18:19 - 18:43]
56-
// CHECK-EXPANDED-NEXT: `-MethodBodyScope {{.*}}, [18:29 - 18:43]
56+
// CHECK-EXPANDED-NEXT: `-FunctionBodyScope {{.*}}, [18:29 - 18:43]
5757
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [18:29 - 18:43]
5858
// CHECK-EXPANDED-NEXT: `-TopLevelCodeScope {{.*}}, [21:1 - 21:28]
5959
// CHECK-EXPANDED-NEXT: `-BraceStmtScope {{.*}}, [21:1 - 21:28]

0 commit comments

Comments
 (0)