@@ -3343,11 +3343,19 @@ class ArgEmitter {
3343
3343
void emitExpanded (ArgumentSource &&arg, AbstractionPattern origParamType) {
3344
3344
assert (!arg.isLValue () && " argument is l-value but parameter is tuple?" );
3345
3345
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
+
3346
3354
// If we're working with an r-value, just expand it out and emit
3347
3355
// all the elements individually.
3356
+ // FIXME: this code is not doing the right thing with packs
3348
3357
if (arg.isRValue ()) {
3349
- if (CanTupleType substArgType =
3350
- dyn_cast<TupleType>(arg.getSubstRValueType ())) {
3358
+ if (CanTupleType substArgType = dyn_cast<TupleType>(substType)) {
3351
3359
// The original type isn't necessarily a tuple.
3352
3360
if (!origParamType.matchesTuple (substArgType))
3353
3361
origParamType = origParamType.getTupleElementType (0 );
@@ -3376,22 +3384,28 @@ class ArgEmitter {
3376
3384
Expr *e = std::move (arg).asKnownExpr ();
3377
3385
3378
3386
// 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,
3384
3398
[&](TupleElementGenerator &elt) {
3385
3399
if (!elt.isOrigPackExpansion ()) {
3386
- emit (tuple-> getElement (elt.getSubstIndex ()), elt.getOrigType ());
3400
+ emit (getElementExpr (elt.getSubstIndex ()), elt.getOrigType ());
3387
3401
return ;
3388
3402
}
3389
3403
3390
3404
auto substEltTypes = elt.getSubstTypes ();
3391
3405
SmallVector<ArgumentSource, 4 > eltArgs;
3392
3406
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));
3395
3409
}
3396
3410
emitPackArg (eltArgs, elt.getOrigType ());
3397
3411
});
0 commit comments