Skip to content

Commit 552ad07

Browse files
committed
Handle vanishing tuples correctly (or more correctly) in arg emission.
1 parent 20de7d1 commit 552ad07

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3343,11 +3343,19 @@ class ArgEmitter {
33433343
void emitExpanded(ArgumentSource &&arg, AbstractionPattern origParamType) {
33443344
assert(!arg.isLValue() && "argument is l-value but parameter is tuple?");
33453345

3346+
// If the original parameter type is a vanishing tuple, we want to emit
3347+
// this as if the argument source was wrapped in an extra level of
3348+
// tuple literal.
3349+
bool origTupleVanishes =
3350+
origParamType.getVanishingTupleElementPatternType().hasValue();
3351+
3352+
auto substType = arg.getSubstRValueType();
3353+
33463354
// If we're working with an r-value, just expand it out and emit
33473355
// all the elements individually.
3356+
// FIXME: this code is not doing the right thing with packs
33483357
if (arg.isRValue()) {
3349-
if (CanTupleType substArgType =
3350-
dyn_cast<TupleType>(arg.getSubstRValueType())) {
3358+
if (CanTupleType substArgType = dyn_cast<TupleType>(substType)) {
33513359
// The original type isn't necessarily a tuple.
33523360
if (!origParamType.matchesTuple(substArgType))
33533361
origParamType = origParamType.getTupleElementType(0);
@@ -3376,22 +3384,28 @@ class ArgEmitter {
33763384
Expr *e = std::move(arg).asKnownExpr();
33773385

33783386
// If the source expression is a tuple literal, we can break it
3379-
// up directly.
3380-
if (auto tuple = dyn_cast<TupleExpr>(e)) {
3381-
auto substTupleType =
3382-
cast<TupleType>(e->getType()->getCanonicalType());
3383-
origParamType.forEachTupleElement(substTupleType,
3387+
// up directly. We can also do this if the orig type is a vanishing
3388+
// tuple, because we want to treat that like it was the sole element
3389+
// of a tuple. Note that vanishing tuples take priority: the
3390+
// singleton element could itself be a tuple.
3391+
auto tupleExpr = dyn_cast<TupleExpr>(e);
3392+
if (origTupleVanishes || tupleExpr) {
3393+
auto getElementExpr = [&](unsigned index) {
3394+
assert(!origTupleVanishes || index == 0);
3395+
return (origTupleVanishes ? e : tupleExpr->getElement(index));
3396+
};
3397+
origParamType.forEachTupleElement(substType,
33843398
[&](TupleElementGenerator &elt) {
33853399
if (!elt.isOrigPackExpansion()) {
3386-
emit(tuple->getElement(elt.getSubstIndex()), elt.getOrigType());
3400+
emit(getElementExpr(elt.getSubstIndex()), elt.getOrigType());
33873401
return;
33883402
}
33893403

33903404
auto substEltTypes = elt.getSubstTypes();
33913405
SmallVector<ArgumentSource, 4> eltArgs;
33923406
eltArgs.reserve(substEltTypes.size());
3393-
for (auto i : range(elt.getSubstIndex(), substEltTypes.size())) {
3394-
eltArgs.emplace_back(tuple->getElement(i));
3407+
for (auto i : elt.getSubstIndexRange()) {
3408+
eltArgs.emplace_back(getElementExpr(i));
33953409
}
33963410
emitPackArg(eltArgs, elt.getOrigType());
33973411
});

0 commit comments

Comments
 (0)