Skip to content

Commit 025921c

Browse files
committed
Parse: Move the lookup of 'self' for a SuperRefExpr to preCheckExpression()
1 parent fe9d1ed commit 025921c

File tree

4 files changed

+41
-31
lines changed

4 files changed

+41
-31
lines changed

include/swift/AST/Expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ class SuperRefExpr : public Expr {
13321332
: Expr(ExprKind::SuperRef, Implicit, SuperTy), Self(Self), Loc(Loc) {}
13331333

13341334
VarDecl *getSelf() const { return Self; }
1335+
void setSelf(VarDecl *self) { Self = self; }
13351336

13361337
SourceLoc getSuperLoc() const { return Loc; }
13371338
SourceRange getSourceRange() const { return Loc; }

lib/Parse/ParseExpr.cpp

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -853,29 +853,6 @@ UnresolvedDeclRefExpr *Parser::parseExprOperator() {
853853
return new (Context) UnresolvedDeclRefExpr(name, refKind, DeclNameLoc(loc));
854854
}
855855

856-
static VarDecl *getImplicitSelfDeclForSuperContext(Parser &P,
857-
DeclContext *DC,
858-
SourceLoc Loc) {
859-
auto *methodContext = DC->getInnermostMethodContext();
860-
if (!methodContext) {
861-
P.diagnose(Loc, diag::super_not_in_class_method);
862-
return nullptr;
863-
}
864-
865-
// Do an actual lookup for 'self' in case it shows up in a capture list.
866-
auto *methodSelf = methodContext->getImplicitSelfDecl();
867-
auto *lookupSelf = P.lookupInScope(DeclNameRef(P.Context.Id_self));
868-
if (lookupSelf && lookupSelf != methodSelf) {
869-
// FIXME: This is the wrong diagnostic for if someone manually declares a
870-
// variable named 'self' using backticks.
871-
P.diagnose(Loc, diag::super_in_closure_with_capture);
872-
P.diagnose(lookupSelf->getLoc(), diag::super_in_closure_with_capture_here);
873-
return nullptr;
874-
}
875-
876-
return methodSelf;
877-
}
878-
879856
/// parseExprSuper
880857
///
881858
/// expr-super:
@@ -903,12 +880,8 @@ ParserResult<Expr> Parser::parseExprSuper() {
903880
return nullptr;
904881
}
905882

906-
VarDecl *selfDecl =
907-
getImplicitSelfDeclForSuperContext(*this, CurDeclContext, superLoc);
908-
if (!selfDecl)
909-
return makeParserResult(new (Context) ErrorExpr(superLoc));
910-
911-
return makeParserResult(new (Context) SuperRefExpr(selfDecl, superLoc,
883+
return makeParserResult(new (Context) SuperRefExpr(/*selfDecl=*/nullptr,
884+
superLoc,
912885
/*Implicit=*/false));
913886
}
914887

lib/Sema/TypeCheckCaptures.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,10 @@ class FindCapturedVars : public ASTWalker {
572572

573573
// When we see a reference to the 'super' expression, capture 'self' decl.
574574
if (auto *superE = dyn_cast<SuperRefExpr>(E)) {
575-
if (CurDC->isChildContextOf(superE->getSelf()->getDeclContext()))
576-
addCapture(CapturedValue(superE->getSelf(), 0, superE->getLoc()));
575+
if (auto *selfDecl = superE->getSelf()) {
576+
if (CurDC->isChildContextOf(selfDecl->getDeclContext()))
577+
addCapture(CapturedValue(selfDecl, 0, superE->getLoc()));
578+
}
577579
return { false, superE };
578580
}
579581

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,29 @@ namespace {
11141114

11151115
bool shouldWalkCaptureInitializerExpressions() override { return true; }
11161116

1117+
VarDecl *getImplicitSelfDeclForSuperContext(SourceLoc Loc) {
1118+
auto *methodContext = DC->getInnermostMethodContext();
1119+
if (!methodContext) {
1120+
Ctx.Diags.diagnose(Loc, diag::super_not_in_class_method);
1121+
return nullptr;
1122+
}
1123+
1124+
// Do an actual lookup for 'self' in case it shows up in a capture list.
1125+
auto *methodSelf = methodContext->getImplicitSelfDecl();
1126+
auto *lookupSelf = ASTScope::lookupSingleLocalDecl(DC->getParentSourceFile(),
1127+
Ctx.Id_self, Loc);
1128+
if (lookupSelf && lookupSelf != methodSelf) {
1129+
// FIXME: This is the wrong diagnostic for if someone manually declares a
1130+
// variable named 'self' using backticks.
1131+
Ctx.Diags.diagnose(Loc, diag::super_in_closure_with_capture);
1132+
Ctx.Diags.diagnose(lookupSelf->getLoc(),
1133+
diag::super_in_closure_with_capture_here);
1134+
return nullptr;
1135+
}
1136+
1137+
return methodSelf;
1138+
}
1139+
11171140
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
11181141
// If this is a call, record the argument expression.
11191142
if (auto call = dyn_cast<ApplyExpr>(expr)) {
@@ -1156,6 +1179,17 @@ namespace {
11561179
return std::make_pair(recursive, expr);
11571180
};
11581181

1182+
// Resolve 'super' references.
1183+
if (auto *superRef = dyn_cast<SuperRefExpr>(expr)) {
1184+
auto loc = superRef->getLoc();
1185+
auto *selfDecl = getImplicitSelfDeclForSuperContext(loc);
1186+
if (selfDecl == nullptr)
1187+
return finish(true, new (Ctx) ErrorExpr(loc));
1188+
1189+
superRef->setSelf(selfDecl);
1190+
return finish(true, superRef);
1191+
}
1192+
11591193
// For closures, type-check the patterns and result type as written,
11601194
// but do not walk into the body. That will be type-checked after
11611195
// we've determine the complete function type.

0 commit comments

Comments
 (0)