Skip to content

Commit b4bf12f

Browse files
committed
[CSApply] Correctly update new trailing closure index
Update when coercing call arguments to account for variadics and default arguments.
1 parent 5b14bf9 commit b4bf12f

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

lib/Sema/CSApply.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5837,8 +5837,9 @@ Expr *ExprRewriter::coerceCallArguments(
58375837
// Apply labels to arguments.
58385838
AnyFunctionType::relabelParams(args, argLabels);
58395839

5840-
auto unlabeledTrailingClosureIndex =
5840+
auto oldTrailingClosureIndex =
58415841
arg->getUnlabeledTrailingClosureIndexOfPackedArgument();
5842+
Optional<unsigned> newTrailingClosureIndex;
58425843

58435844
// Determine the parameter bindings that were applied.
58445845
auto *locatorPtr = cs.getConstraintLocator(locator);
@@ -5912,6 +5913,12 @@ Expr *ExprRewriter::coerceCallArguments(
59125913
auto arg = getArg(argIdx);
59135914
auto argType = cs.getType(arg);
59145915

5916+
// Update the trailing closure index if needed.
5917+
if (oldTrailingClosureIndex && *oldTrailingClosureIndex == argIdx) {
5918+
assert(!newTrailingClosureIndex);
5919+
newTrailingClosureIndex = newArgs.size();
5920+
}
5921+
59155922
// If the argument type exactly matches, this just works.
59165923
if (argType->isEqual(param.getPlainType())) {
59175924
variadicArgs.push_back(arg);
@@ -5974,6 +5981,12 @@ Expr *ExprRewriter::coerceCallArguments(
59745981
auto arg = getArg(argIdx);
59755982
auto argType = cs.getType(arg);
59765983

5984+
// Update the trailing closure index if needed.
5985+
if (oldTrailingClosureIndex && *oldTrailingClosureIndex == argIdx) {
5986+
assert(!newTrailingClosureIndex);
5987+
newTrailingClosureIndex = newArgs.size();
5988+
}
5989+
59775990
// Save the original label location.
59785991
newLabelLocs.push_back(getLabelLoc(argIdx));
59795992

@@ -6089,14 +6102,17 @@ Expr *ExprRewriter::coerceCallArguments(
60896102
assert(newArgs.size() == newParams.size());
60906103
assert(newArgs.size() == newLabels.size());
60916104
assert(newArgs.size() == newLabelLocs.size());
6105+
assert(oldTrailingClosureIndex.hasValue() ==
6106+
newTrailingClosureIndex.hasValue());
6107+
assert(!newTrailingClosureIndex || *newTrailingClosureIndex < newArgs.size());
60926108

60936109
// This is silly. SILGen gets confused if a 'self' parameter is wrapped
60946110
// in a ParenExpr sometimes.
60956111
if (!argTuple && !argParen &&
60966112
(params[0].getValueOwnership() == ValueOwnership::Default ||
60976113
params[0].getValueOwnership() == ValueOwnership::InOut)) {
60986114
assert(newArgs.size() == 1);
6099-
assert(!unlabeledTrailingClosureIndex);
6115+
assert(!newTrailingClosureIndex);
61006116
return newArgs[0];
61016117
}
61026118

@@ -6111,7 +6127,7 @@ Expr *ExprRewriter::coerceCallArguments(
61116127
bool isImplicit = arg->isImplicit();
61126128
arg = new (ctx) ParenExpr(
61136129
lParenLoc, newArgs[0], rParenLoc,
6114-
static_cast<bool>(unlabeledTrailingClosureIndex));
6130+
static_cast<bool>(newTrailingClosureIndex));
61156131
arg->setImplicit(isImplicit);
61166132
}
61176133
} else {
@@ -6126,7 +6142,7 @@ Expr *ExprRewriter::coerceCallArguments(
61266142
} else {
61276143
// Build a new TupleExpr, re-using source location information.
61286144
arg = TupleExpr::create(ctx, lParenLoc, rParenLoc, newArgs, newLabels,
6129-
newLabelLocs, unlabeledTrailingClosureIndex,
6145+
newLabelLocs, newTrailingClosureIndex,
61306146
/*implicit=*/arg->isImplicit());
61316147
}
61326148
}

0 commit comments

Comments
 (0)