Skip to content

Commit 1b5dab0

Browse files
committed
Fix issue where closure implicit self check was being run on expr that wasn't member of closure
1 parent 3be14e0 commit 1b5dab0

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,30 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
20042004
diag.fixItInsertAfter(closureExpr->getLoc(), " [self] in" + trailing);
20052005
}
20062006
};
2007+
2008+
// A walker that verifies whether or not `exprToMatch`
2009+
// is a descendent of the AST node being walked
2010+
class ExprIsDescendantWalker : public BaseDiagnosticWalker {
2011+
Expr *exprToMatch;
2012+
public:
2013+
bool exprIsDescendant = false;
2014+
2015+
explicit ExprIsDescendantWalker(Expr *exprToMatch)
2016+
: exprToMatch(exprToMatch) { }
2017+
2018+
bool shouldWalkIntoSeparatelyCheckedClosure(ClosureExpr *expr) override {
2019+
return true;
2020+
}
2021+
2022+
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
2023+
if (E == exprToMatch) {
2024+
exprIsDescendant = true;
2025+
return Action::Stop();
2026+
}
2027+
2028+
return Action::Continue(E);
2029+
}
2030+
};
20072031

20082032
auto &ctx = DC->getASTContext();
20092033
AbstractClosureExpr *ACE = nullptr;
@@ -2015,6 +2039,18 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
20152039
DC = DC->getParent();
20162040
}
20172041
}
2042+
2043+
// Verify E is actually a descendant of ACE before we use it.
2044+
// Otherwise we'd be diagnosing E within the context of a closure
2045+
// that it isn't actually a part of.
2046+
if (ACE) {
2047+
auto isDescendantWalker = ExprIsDescendantWalker(const_cast<Expr *>(E));
2048+
ACE->walk(isDescendantWalker);
2049+
if (!isDescendantWalker.exprIsDescendant) {
2050+
ACE = nullptr;
2051+
}
2052+
}
2053+
20182054
const_cast<Expr *>(E)->walk(DiagnoseWalker(ctx, ACE));
20192055
}
20202056

0 commit comments

Comments
 (0)