Skip to content

Commit 3ad8ea8

Browse files
committed
[CSFix] Add a fix to ignore function builder body which fails pre-check
Fix is anchored on a `BraceStmt` associated with an invalid closure. It's diagnosing the problem by calling `ConstraintSystem::preCheckExpression` for all expressions in the body without suppressing errors.
1 parent fddfd6d commit 3ad8ea8

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

lib/Sema/CSFix.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,3 +1551,40 @@ AllowKeyPathWithoutComponents::create(ConstraintSystem &cs,
15511551
ConstraintLocator *locator) {
15521552
return new (cs.getAllocator()) AllowKeyPathWithoutComponents(cs, locator);
15531553
}
1554+
1555+
bool IgnoreInvalidFunctionBuilderBody::diagnose(const Solution &solution,
1556+
bool asNote) const {
1557+
auto *S = getAnchor().get<Stmt *>();
1558+
1559+
class PreCheckWalker : public ASTWalker {
1560+
DeclContext *DC;
1561+
1562+
public:
1563+
PreCheckWalker(DeclContext *dc) : DC(dc) {}
1564+
1565+
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
1566+
auto hasError = ConstraintSystem::preCheckExpression(E, DC);
1567+
return std::make_pair(false, hasError ? nullptr : E);
1568+
}
1569+
1570+
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
1571+
return std::make_pair(true, S);
1572+
}
1573+
1574+
// Ignore patterns because function builder pre-check does so as well.
1575+
std::pair<bool, Pattern *> walkToPatternPre(Pattern *P) override {
1576+
return std::make_pair(false, P);
1577+
}
1578+
};
1579+
1580+
PreCheckWalker walker(solution.getDC());
1581+
S->walk(walker);
1582+
1583+
return true;
1584+
}
1585+
1586+
IgnoreInvalidFunctionBuilderBody *
1587+
IgnoreInvalidFunctionBuilderBody::create(ConstraintSystem &cs,
1588+
ConstraintLocator *locator) {
1589+
return new (cs.getAllocator()) IgnoreInvalidFunctionBuilderBody(cs, locator);
1590+
}

lib/Sema/CSFix.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ enum class FixKind : uint8_t {
276276

277277
/// Allow key path expressions with no components.
278278
AllowKeyPathWithoutComponents,
279+
280+
/// Ignore function builder body which fails `pre-check` call.
281+
IgnoreInvalidFunctionBuilderBody,
279282
};
280283

281284
class ConstraintFix {
@@ -1980,6 +1983,26 @@ class AllowKeyPathWithoutComponents final : public ConstraintFix {
19801983
ConstraintLocator *locator);
19811984
};
19821985

1986+
class IgnoreInvalidFunctionBuilderBody final : public ConstraintFix {
1987+
IgnoreInvalidFunctionBuilderBody(ConstraintSystem &cs,
1988+
ConstraintLocator *locator)
1989+
: ConstraintFix(cs, FixKind::IgnoreInvalidFunctionBuilderBody, locator) {}
1990+
1991+
public:
1992+
std::string getName() const override {
1993+
return "ignore invalid function builder body";
1994+
}
1995+
1996+
bool diagnose(const Solution &solution, bool asNote = false) const override;
1997+
1998+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
1999+
return diagnose(*commonFixes.front().first);
2000+
}
2001+
2002+
static IgnoreInvalidFunctionBuilderBody *create(ConstraintSystem &cs,
2003+
ConstraintLocator *locator);
2004+
};
2005+
19832006
} // end namespace constraints
19842007
} // end namespace swift
19852008

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9997,7 +9997,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
99979997
case FixKind::AllowCoercionToForceCast:
99989998
case FixKind::SpecifyKeyPathRootType:
99999999
case FixKind::SpecifyLabelToAssociateTrailingClosure:
10000-
case FixKind::AllowKeyPathWithoutComponents: {
10000+
case FixKind::AllowKeyPathWithoutComponents:
10001+
case FixKind::IgnoreInvalidFunctionBuilderBody: {
1000110002
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
1000210003
}
1000310004

0 commit comments

Comments
 (0)