Skip to content

Commit 1bfb0b0

Browse files
committed
[ConstraintSystem] Extend invalid function body fix to cover constraint generation failures
Ignore function builder body if it emits at least one diagnostic during constraint generation. Resolves: rdar://problem/65983237
1 parent 0990fa9 commit 1bfb0b0

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,7 +1669,7 @@ ConstraintSystem::matchFunctionBuilder(
16691669
if (!shouldAttemptFixes())
16701670
return getTypeMatchFailure(locator);
16711671

1672-
if (recordFix(IgnoreInvalidFunctionBuilderBody::create(
1672+
if (recordFix(IgnoreInvalidFunctionBuilderBody::duringPreCheck(
16731673
*this, getConstraintLocator(fn.getBody()))))
16741674
return getTypeMatchFailure(locator);
16751675

@@ -1711,9 +1711,23 @@ ConstraintSystem::matchFunctionBuilder(
17111711
BuilderClosureVisitor visitor(getASTContext(), this, dc, builderType,
17121712
bodyResultType);
17131713

1714-
auto applied = visitor.apply(fn.getBody());
1715-
if (!applied)
1716-
return getTypeMatchFailure(locator);
1714+
Optional<AppliedBuilderTransform> applied = None;
1715+
{
1716+
DiagnosticTransaction transaction(dc->getASTContext().Diags);
1717+
1718+
applied = visitor.apply(fn.getBody());
1719+
if (!applied)
1720+
return getTypeMatchFailure(locator);
1721+
1722+
if (transaction.hasDiagnostics()) {
1723+
if (recordFix(
1724+
IgnoreInvalidFunctionBuilderBody::duringConstraintGeneration(
1725+
*this, getConstraintLocator(fn.getBody()))))
1726+
return getTypeMatchFailure(locator);
1727+
1728+
return getTypeMatchSuccess();
1729+
}
1730+
}
17171731

17181732
Type transformedType = getType(applied->returnExpr);
17191733
assert(transformedType && "Missing type");

lib/Sema/CSFix.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,14 @@ AllowKeyPathWithoutComponents::create(ConstraintSystem &cs,
15541554

15551555
bool IgnoreInvalidFunctionBuilderBody::diagnose(const Solution &solution,
15561556
bool asNote) const {
1557+
switch (Phase) {
1558+
// Handled below
1559+
case ErrorInPhase::PreCheck:
1560+
break;
1561+
case ErrorInPhase::ConstraintGeneration:
1562+
return true; // Already diagnosed by `matchFunctionBuilder`.
1563+
}
1564+
15571565
auto *S = getAnchor().get<Stmt *>();
15581566

15591567
class PreCheckWalker : public ASTWalker {
@@ -1590,8 +1598,8 @@ bool IgnoreInvalidFunctionBuilderBody::diagnose(const Solution &solution,
15901598
return walker.diagnosed();
15911599
}
15921600

1593-
IgnoreInvalidFunctionBuilderBody *
1594-
IgnoreInvalidFunctionBuilderBody::create(ConstraintSystem &cs,
1595-
ConstraintLocator *locator) {
1596-
return new (cs.getAllocator()) IgnoreInvalidFunctionBuilderBody(cs, locator);
1601+
IgnoreInvalidFunctionBuilderBody *IgnoreInvalidFunctionBuilderBody::create(
1602+
ConstraintSystem &cs, ErrorInPhase phase, ConstraintLocator *locator) {
1603+
return new (cs.getAllocator())
1604+
IgnoreInvalidFunctionBuilderBody(cs, phase, locator);
15971605
}

lib/Sema/CSFix.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,9 +1984,17 @@ class AllowKeyPathWithoutComponents final : public ConstraintFix {
19841984
};
19851985

19861986
class IgnoreInvalidFunctionBuilderBody final : public ConstraintFix {
1987-
IgnoreInvalidFunctionBuilderBody(ConstraintSystem &cs,
1987+
enum class ErrorInPhase {
1988+
PreCheck,
1989+
ConstraintGeneration,
1990+
};
1991+
1992+
ErrorInPhase Phase;
1993+
1994+
IgnoreInvalidFunctionBuilderBody(ConstraintSystem &cs, ErrorInPhase phase,
19881995
ConstraintLocator *locator)
1989-
: ConstraintFix(cs, FixKind::IgnoreInvalidFunctionBuilderBody, locator) {}
1996+
: ConstraintFix(cs, FixKind::IgnoreInvalidFunctionBuilderBody, locator),
1997+
Phase(phase) {}
19901998

19911999
public:
19922000
std::string getName() const override {
@@ -1999,8 +2007,19 @@ class IgnoreInvalidFunctionBuilderBody final : public ConstraintFix {
19992007
return diagnose(*commonFixes.front().first);
20002008
}
20012009

2002-
static IgnoreInvalidFunctionBuilderBody *create(ConstraintSystem &cs,
2003-
ConstraintLocator *locator);
2010+
static IgnoreInvalidFunctionBuilderBody *
2011+
duringPreCheck(ConstraintSystem &cs, ConstraintLocator *locator) {
2012+
return create(cs, ErrorInPhase::PreCheck, locator);
2013+
}
2014+
2015+
static IgnoreInvalidFunctionBuilderBody *
2016+
duringConstraintGeneration(ConstraintSystem &cs, ConstraintLocator *locator) {
2017+
return create(cs, ErrorInPhase::ConstraintGeneration, locator);
2018+
}
2019+
2020+
private:
2021+
static IgnoreInvalidFunctionBuilderBody *
2022+
create(ConstraintSystem &cs, ErrorInPhase phase, ConstraintLocator *locator);
20042023
};
20052024

20062025
} // end namespace constraints

0 commit comments

Comments
 (0)