Skip to content

Commit f40cf4c

Browse files
committed
[CS] Use performSyntacticDiagnosticsForTarget for function builder
Add a case for `SolutionApplicationTarget::Kind::function` and move the logic over.
1 parent be607d1 commit f40cf4c

File tree

2 files changed

+54
-60
lines changed

2 files changed

+54
-60
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,64 +1453,6 @@ BraceStmt *swift::applyFunctionBuilderTransform(
14531453
captured.first, captured.second)));
14541454
}
14551455

1456-
/// Produce any additional syntactic diagnostics for the body of a function
1457-
/// that had a function builder applied.
1458-
static void performAddOnDiagnostics(BraceStmt *stmt, DeclContext *dc) {
1459-
class AddOnDiagnosticWalker : public ASTWalker {
1460-
SmallVector<DeclContext *, 4> dcStack;
1461-
1462-
public:
1463-
AddOnDiagnosticWalker(DeclContext *dc) {
1464-
dcStack.push_back(dc);
1465-
}
1466-
1467-
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
1468-
performSyntacticExprDiagnostics(
1469-
expr, dcStack.back(), /*isExprStmt=*/false);
1470-
1471-
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
1472-
if (closure->wasSeparatelyTypeChecked()) {
1473-
dcStack.push_back(closure);
1474-
return { true, expr };
1475-
}
1476-
}
1477-
1478-
return { false, expr };
1479-
}
1480-
1481-
Expr *walkToExprPost(Expr *expr) override {
1482-
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
1483-
if (closure->wasSeparatelyTypeChecked()) {
1484-
assert(dcStack.back() == closure);
1485-
dcStack.pop_back();
1486-
}
1487-
}
1488-
1489-
return expr;
1490-
}
1491-
1492-
std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
1493-
performStmtDiagnostics(dcStack.back()->getASTContext(), stmt);
1494-
return { true, stmt };
1495-
}
1496-
1497-
std::pair<bool, Pattern*> walkToPatternPre(Pattern *pattern) override {
1498-
return { false, pattern };
1499-
}
1500-
1501-
bool walkToTypeLocPre(TypeLoc &typeLoc) override { return false; }
1502-
1503-
bool walkToTypeReprPre(TypeRepr *typeRepr) override { return false; }
1504-
1505-
bool walkToParameterListPre(ParameterList *params) override {
1506-
return false;
1507-
}
1508-
};
1509-
1510-
AddOnDiagnosticWalker walker(dc);
1511-
stmt->walk(walker);
1512-
}
1513-
15141456
Optional<BraceStmt *> TypeChecker::applyFunctionBuilderBodyTransform(
15151457
FuncDecl *func, Type builderType) {
15161458
// Pre-check the body: pre-check any expressions in it and look
@@ -1629,7 +1571,7 @@ Optional<BraceStmt *> TypeChecker::applyFunctionBuilderBodyTransform(
16291571
if (auto result = cs.applySolution(
16301572
solutions.front(),
16311573
SolutionApplicationTarget(func))) {
1632-
performAddOnDiagnostics(result->getFunctionBody(), func);
1574+
performSyntacticDiagnosticsForTarget(*result, /*isExprStmt*/ false);
16331575
return result->getFunctionBody();
16341576
}
16351577

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,54 @@ bool GenericRequirementsCheckListener::diagnoseUnsatisfiedRequirement(
19951995
return false;
19961996
}
19971997

1998+
namespace {
1999+
/// Produce any additional syntactic diagnostics for the body of a function
2000+
/// that had a function builder applied.
2001+
class FunctionSyntacticDiagnosticWalker : public ASTWalker {
2002+
SmallVector<DeclContext *, 4> dcStack;
2003+
2004+
public:
2005+
FunctionSyntacticDiagnosticWalker(DeclContext *dc) { dcStack.push_back(dc); }
2006+
2007+
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
2008+
performSyntacticExprDiagnostics(expr, dcStack.back(), /*isExprStmt=*/false);
2009+
2010+
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
2011+
if (closure->wasSeparatelyTypeChecked()) {
2012+
dcStack.push_back(closure);
2013+
return {true, expr};
2014+
}
2015+
}
2016+
2017+
return {false, expr};
2018+
}
2019+
2020+
Expr *walkToExprPost(Expr *expr) override {
2021+
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
2022+
if (closure->wasSeparatelyTypeChecked()) {
2023+
assert(dcStack.back() == closure);
2024+
dcStack.pop_back();
2025+
}
2026+
}
2027+
2028+
return expr;
2029+
}
2030+
2031+
std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
2032+
performStmtDiagnostics(dcStack.back()->getASTContext(), stmt);
2033+
return {true, stmt};
2034+
}
2035+
2036+
std::pair<bool, Pattern *> walkToPatternPre(Pattern *pattern) override {
2037+
return {false, pattern};
2038+
}
2039+
2040+
bool walkToTypeLocPre(TypeLoc &typeLoc) override { return false; }
2041+
bool walkToTypeReprPre(TypeRepr *typeRepr) override { return false; }
2042+
bool walkToParameterListPre(ParameterList *params) override { return false; }
2043+
};
2044+
} // end anonymous namespace
2045+
19982046
void constraints::performSyntacticDiagnosticsForTarget(
19992047
const SolutionApplicationTarget &target, bool isExprStmt) {
20002048
auto *dc = target.getDeclContext();
@@ -2011,7 +2059,11 @@ void constraints::performSyntacticDiagnosticsForTarget(
20112059
}
20122060
return;
20132061
}
2014-
case SolutionApplicationTarget::Kind::function:
2062+
case SolutionApplicationTarget::Kind::function: {
2063+
FunctionSyntacticDiagnosticWalker walker(dc);
2064+
target.getFunctionBody()->walk(walker);
2065+
return;
2066+
}
20152067
case SolutionApplicationTarget::Kind::stmtCondition:
20162068
case SolutionApplicationTarget::Kind::caseLabelItem:
20172069
case SolutionApplicationTarget::Kind::patternBinding:

0 commit comments

Comments
 (0)