Skip to content

Commit 7701f4e

Browse files
committed
[CSSimplify] Avoid resolving extraneous (trailing) closures
If a (trailing) closure is determined to be an extraneous argument for one of the overload choices it needs to be marked as hole as eagerly as possible and prevented from being resolved because otherwise it's going to be disconnected from the rest of the constraint system and resolution might not be able to find all of the referenced variables. This could result either in crashes or superfluous diagnostics. Resolves: rdar://141012049
1 parent 64fb19b commit 7701f4e

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,6 +1620,21 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
16201620
cs, contextualType, extraArguments,
16211621
cs.getConstraintLocator(locator));
16221622

1623+
for (const auto &extraArg : extraArguments) {
1624+
auto argument = argList->get(extraArg.first);
1625+
auto argType = extraArg.second.getPlainType();
1626+
1627+
// Prevent closure resolution by binding it to a placeholder
1628+
// because the main issue here is invalid overload and
1629+
// errors produced from the closure body are going to be
1630+
// superfluous.
1631+
if (isExpr<ClosureExpr>(argument.getExpr())) {
1632+
cs.recordTypeVariablesAsHoles(argType);
1633+
} else {
1634+
cs.recordAnyTypeVarAsPotentialHole(argType);
1635+
}
1636+
}
1637+
16231638
if (cs.recordFix(fix, /*impact=*/extraArguments.size() * 5))
16241639
return cs.getTypeMatchFailure(locator);
16251640
}
@@ -11371,6 +11386,12 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFallbackTypeConstraint(
1137111386
return SolutionKind::Unsolved;
1137211387
}
1137311388

11389+
// Propagate placeholders into an inferred closure type. Without this
11390+
// we'd produce superfluous diagnostics about parameter/result types.
11391+
if (defaultableType->isPlaceholder() && locator.directlyAt<ClosureExpr>()) {
11392+
recordTypeVariablesAsHoles(fallbackType);
11393+
}
11394+
1137411395
// Otherwise, any type is fine.
1137511396
return SolutionKind::Solved;
1137611397
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
func test(_ v: [Int]) {
4+
let result = v.filter { }.flatMap(\.wrong) {
5+
// expected-error@-1 {{type for closure argument list expects 1 argument, which cannot be implicitly ignored}}
6+
// expected-error@-2 {{cannot convert value of type '()' to closure result type 'Bool'}}
7+
// expected-error@-3 {{value of type 'Int' has no member 'wrong'}}
8+
// expected-error@-4 {{extra trailing closure passed in call}}
9+
print(result)
10+
}
11+
12+
let otherResult = v.filter { _ in false }.flatMap(\.wrong, { $0 }, 42)
13+
// expected-error@-1 {{value of type 'Int' has no member 'wrong'}}
14+
// expected-error@-2 {{extra arguments at positions #2, #3 in call}}
15+
}

0 commit comments

Comments
 (0)