@@ -1105,8 +1105,10 @@ constraints::getCompletionArgInfo(ASTNode anchor, ConstraintSystem &CS) {
1105
1105
class ArgumentFailureTracker : public MatchCallArgumentListener {
1106
1106
protected:
1107
1107
ConstraintSystem &CS;
1108
+ NullablePtr<ValueDecl> Callee;
1108
1109
SmallVectorImpl<AnyFunctionType::Param> &Arguments;
1109
1110
ArrayRef<AnyFunctionType::Param> Parameters;
1111
+ Optional<unsigned> UnlabeledTrailingClosureArgIndex;
1110
1112
ConstraintLocatorBuilder Locator;
1111
1113
1112
1114
private:
@@ -1138,11 +1140,14 @@ class ArgumentFailureTracker : public MatchCallArgumentListener {
1138
1140
}
1139
1141
1140
1142
public:
1141
- ArgumentFailureTracker(ConstraintSystem &cs,
1143
+ ArgumentFailureTracker(ConstraintSystem &cs, ValueDecl *callee,
1142
1144
SmallVectorImpl<AnyFunctionType::Param> &args,
1143
1145
ArrayRef<AnyFunctionType::Param> params,
1146
+ Optional<unsigned> unlabeledTrailingClosureArgIndex,
1144
1147
ConstraintLocatorBuilder locator)
1145
- : CS(cs), Arguments(args), Parameters(params), Locator(locator) {}
1148
+ : CS(cs), Callee(callee), Arguments(args), Parameters(params),
1149
+ UnlabeledTrailingClosureArgIndex(unlabeledTrailingClosureArgIndex),
1150
+ Locator(locator) {}
1146
1151
1147
1152
~ArgumentFailureTracker() override {
1148
1153
if (!MissingArguments.empty()) {
@@ -1172,6 +1177,19 @@ class ArgumentFailureTracker : public MatchCallArgumentListener {
1172
1177
if (!CS.shouldAttemptFixes())
1173
1178
return true;
1174
1179
1180
+ // If this is a trailing closure, let's check if the call is
1181
+ // to an init of a callable type. If so, let's not record it
1182
+ // as extraneous since it would be matched against implicitly
1183
+ // injected `.callAsFunction` call.
1184
+ if (UnlabeledTrailingClosureArgIndex &&
1185
+ argIdx == *UnlabeledTrailingClosureArgIndex && Callee) {
1186
+ if (auto *ctor = dyn_cast<ConstructorDecl>(Callee.get())) {
1187
+ auto resultTy = ctor->getResultInterfaceType();
1188
+ if (resultTy->isCallableNominalType(CS.DC))
1189
+ return true;
1190
+ }
1191
+ }
1192
+
1175
1193
ExtraArguments.push_back(std::make_pair(argIdx, Arguments[argIdx]));
1176
1194
return false;
1177
1195
}
@@ -1280,12 +1298,15 @@ class CompletionArgumentTracker : public ArgumentFailureTracker {
1280
1298
struct CompletionArgInfo ArgInfo;
1281
1299
1282
1300
public:
1283
- CompletionArgumentTracker(ConstraintSystem &cs,
1301
+ CompletionArgumentTracker(ConstraintSystem &cs, ValueDecl *callee,
1284
1302
SmallVectorImpl<AnyFunctionType::Param> &args,
1285
1303
ArrayRef<AnyFunctionType::Param> params,
1304
+ Optional<unsigned> unlabeledTrailingClosureArgIndex,
1286
1305
ConstraintLocatorBuilder locator,
1287
1306
struct CompletionArgInfo ArgInfo)
1288
- : ArgumentFailureTracker(cs, args, params, locator), ArgInfo(ArgInfo) {}
1307
+ : ArgumentFailureTracker(cs, callee, args, params,
1308
+ unlabeledTrailingClosureArgIndex, locator),
1309
+ ArgInfo(ArgInfo) {}
1289
1310
1290
1311
Optional<unsigned> missingArgument(unsigned paramIdx,
1291
1312
unsigned argInsertIdx) override {
@@ -1695,14 +1716,16 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
1695
1716
if (cs.isForCodeCompletion()) {
1696
1717
if (auto completionInfo = getCompletionArgInfo(locator.getAnchor(), cs)) {
1697
1718
listener = std::make_unique<CompletionArgumentTracker>(
1698
- cs, argsWithLabels, params, locator, *completionInfo);
1719
+ cs, callee, argsWithLabels, params,
1720
+ argList->getFirstTrailingClosureIndex(), locator, *completionInfo);
1699
1721
}
1700
1722
}
1701
1723
if (!listener) {
1702
1724
// We didn't create an argument tracker for code completion. Create a
1703
1725
// normal one.
1704
- listener = std::make_unique<ArgumentFailureTracker>(cs, argsWithLabels,
1705
- params, locator);
1726
+ listener = std::make_unique<ArgumentFailureTracker>(
1727
+ cs, callee, argsWithLabels, params,
1728
+ argList->getFirstTrailingClosureIndex(), locator);
1706
1729
}
1707
1730
auto callArgumentMatch = constraints::matchCallArguments(
1708
1731
argsWithLabels, params, paramInfo,
0 commit comments