Skip to content

Commit 8920da2

Browse files
authored
Merge pull request #34104 from slavapestov/more-astscope-fixes
More ASTScope fixes in preparation for turning off parse-time lookup
2 parents a845c5a + bd7763d commit 8920da2

File tree

6 files changed

+61
-44
lines changed

6 files changed

+61
-44
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/AST/UnqualifiedLookup.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,6 @@ namespace {
144144
static const unsigned targetLookup;
145145
#endif
146146

147-
public: // for exp debugging
148-
unsigned resultsSizeBeforeLocalsPass = ~0;
149-
150147
public:
151148
// clang-format off
152149
UnqualifiedLookupFactory(DeclNameRef Name,
@@ -708,16 +705,10 @@ void UnqualifiedLookupFactory::printScopes(raw_ostream &out) const {
708705

709706
void UnqualifiedLookupFactory::printResults(raw_ostream &out) const {
710707
for (auto i : indices(Results)) {
711-
if (i == resultsSizeBeforeLocalsPass)
712-
out << "============== next pass ============\n";
713708
out << i << ": ";
714709
Results[i].print(out);
715710
out << "\n";
716711
}
717-
if (resultsSizeBeforeLocalsPass == Results.size())
718-
out << "============== next pass ============\n";
719-
if (resultsSizeBeforeLocalsPass == ~0u)
720-
out << "never tried locals\n\n";
721712
}
722713

723714
void UnqualifiedLookupFactory::print(raw_ostream &OS) const {

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/MiscDiagnostics.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,8 @@ bool swift::computeFixitsForOverridenDeclaration(
22822282
namespace {
22832283

22842284
class VarDeclUsageChecker : public ASTWalker {
2285+
DeclContext *DC;
2286+
22852287
DiagnosticEngine &Diags;
22862288
// Keep track of some information about a variable.
22872289
enum {
@@ -2318,7 +2320,8 @@ class VarDeclUsageChecker : public ASTWalker {
23182320
void operator=(const VarDeclUsageChecker &) = delete;
23192321

23202322
public:
2321-
VarDeclUsageChecker(DiagnosticEngine &Diags) : Diags(Diags) {}
2323+
VarDeclUsageChecker(DeclContext *DC,
2324+
DiagnosticEngine &Diags) : DC(DC), Diags(Diags) {}
23222325

23232326
// After we have scanned the entire region, diagnose variables that could be
23242327
// declared with a narrower usage kind.
@@ -3140,14 +3143,27 @@ std::pair<bool, Expr *> VarDeclUsageChecker::walkToExprPre(Expr *E) {
31403143
void VarDeclUsageChecker::handleIfConfig(IfConfigDecl *ICD) {
31413144
struct ConservativeDeclMarker : public ASTWalker {
31423145
VarDeclUsageChecker &VDUC;
3143-
ConservativeDeclMarker(VarDeclUsageChecker &VDUC) : VDUC(VDUC) {}
3146+
SourceFile *SF;
3147+
3148+
ConservativeDeclMarker(VarDeclUsageChecker &VDUC)
3149+
: VDUC(VDUC), SF(VDUC.DC->getParentSourceFile()) {}
31443150

31453151
Expr *walkToExprPost(Expr *E) override {
31463152
// If we see a bound reference to a decl in an inactive #if block, then
31473153
// conservatively mark it read and written. This will silence "variable
31483154
// unused" and "could be marked let" warnings for it.
31493155
if (auto *DRE = dyn_cast<DeclRefExpr>(E))
31503156
VDUC.addMark(DRE->getDecl(), RK_Read|RK_Written);
3157+
else if (auto *declRef = dyn_cast<UnresolvedDeclRefExpr>(E)) {
3158+
auto name = declRef->getName();
3159+
auto loc = declRef->getLoc();
3160+
if (name.isSimpleName() && loc.isValid()) {
3161+
auto *varDecl = dyn_cast_or_null<VarDecl>(
3162+
ASTScope::lookupSingleLocalDecl(SF, name.getFullName(), loc));
3163+
if (varDecl)
3164+
VDUC.addMark(varDecl, RK_Read|RK_Written);
3165+
}
3166+
}
31513167
return E;
31523168
}
31533169
};
@@ -3166,7 +3182,7 @@ void VarDeclUsageChecker::handleIfConfig(IfConfigDecl *ICD) {
31663182
void swift::
31673183
performTopLevelDeclDiagnostics(TopLevelCodeDecl *TLCD) {
31683184
auto &ctx = TLCD->getDeclContext()->getASTContext();
3169-
VarDeclUsageChecker checker(ctx.Diags);
3185+
VarDeclUsageChecker checker(TLCD, ctx.Diags);
31703186
TLCD->walk(checker);
31713187
}
31723188

@@ -3181,7 +3197,7 @@ void swift::performAbstractFuncDeclDiagnostics(AbstractFunctionDecl *AFD) {
31813197
// be checked as part of their parent function or TopLevelCodeDecl.
31823198
if (!AFD->getDeclContext()->isLocalContext()) {
31833199
auto &ctx = AFD->getDeclContext()->getASTContext();
3184-
VarDeclUsageChecker checker(ctx.Diags);
3200+
VarDeclUsageChecker checker(AFD, ctx.Diags);
31853201
AFD->walk(checker);
31863202
}
31873203

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)