Skip to content

Commit f68e8d2

Browse files
committed
[Diagnostics] Don't diagnose inability to infer closure parameter if contextual couldn't be established
If closure is an argument to a call to a missing member or invalid contextual member reference let's not diagnose problems related to inability to infer parameter types because root issue is that context for closure inference couldn't be established.
1 parent 7e4eb9c commit f68e8d2

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
using namespace swift;
4242
using namespace constraints;
4343

44+
static bool hasFixFor(const Solution &solution, ConstraintLocator *locator) {
45+
return llvm::any_of(solution.Fixes, [&locator](const ConstraintFix *fix) {
46+
return fix->getLocator() == locator;
47+
});
48+
}
49+
4450
FailureDiagnostic::~FailureDiagnostic() {}
4551

4652
bool FailureDiagnostic::diagnose(bool asNote) {
@@ -6127,6 +6133,53 @@ bool MissingContextualBaseInMemberRefFailure::diagnoseAsError() {
61276133

61286134
bool UnableToInferClosureParameterType::diagnoseAsError() {
61296135
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
6136+
6137+
// Let's check whether this closure is an argument to
6138+
// a call which couldn't be properly resolved e.g.
6139+
// missing member or invalid contextual reference and
6140+
// if so let's not diagnose this problem because main
6141+
// issue here is inability to establish context for
6142+
// closure inference.
6143+
//
6144+
// TODO(diagnostics): Once we gain an ability to determine
6145+
// originating source of type holes this check could be
6146+
// significantly simplified.
6147+
{
6148+
auto &solution = getSolution();
6149+
6150+
// If there is a contextual mismatch associated with this
6151+
// closure, let's not diagnose any parameter type issues.
6152+
if (hasFixFor(solution, getConstraintLocator(
6153+
closure, LocatorPathElt::ContextualType())))
6154+
return false;
6155+
6156+
if (auto *parentExpr = findParentExpr(closure)) {
6157+
while (parentExpr &&
6158+
(isa<TupleExpr>(parentExpr) || isa<ParenExpr>(parentExpr))) {
6159+
parentExpr = findParentExpr(parentExpr);
6160+
}
6161+
6162+
if (parentExpr) {
6163+
// Missing or invalid member reference in call.
6164+
if (auto *AE = dyn_cast<ApplyExpr>(parentExpr)) {
6165+
if (getType(AE->getFn())->isHole())
6166+
return false;
6167+
}
6168+
6169+
// Any fix anchored on parent expression makes it unnecessary
6170+
// to diagnose unability to infer parameter type because it's
6171+
// an indication that proper context couldn't be established to
6172+
// resolve the closure.
6173+
ASTNode parentNode(parentExpr);
6174+
if (llvm::any_of(solution.Fixes,
6175+
[&parentNode](const ConstraintFix *fix) -> bool {
6176+
return fix->getAnchor() == parentNode;
6177+
}))
6178+
return false;
6179+
}
6180+
}
6181+
}
6182+
61306183
auto paramIdx = getLocator()
61316184
->castLastElementTo<LocatorPathElt::TupleElement>()
61326185
.getIndex();

0 commit comments

Comments
 (0)