@@ -42,6 +42,10 @@ static unsigned getTupleSize(CanType t) {
42
42
43
43
unsigned RValue::getRValueSize (AbstractionPattern pattern, CanType formalType) {
44
44
if (pattern.isTuple ()) {
45
+ if (pattern.doesTupleContainPackExpansionType ())
46
+ return 1 ;
47
+
48
+ // We can use the naive parallel walk here because of the check above.
45
49
unsigned count = 0 ;
46
50
auto formalTupleType = cast<TupleType>(formalType);
47
51
for (auto i : indices (formalTupleType.getElementTypes ())) {
@@ -57,6 +61,10 @@ unsigned RValue::getRValueSize(AbstractionPattern pattern, CanType formalType) {
57
61
// / Return the number of rvalue elements in the given canonical type.
58
62
unsigned RValue::getRValueSize (CanType type) {
59
63
if (auto tupleType = dyn_cast<TupleType>(type)) {
64
+ // Don't recursively expand tuples containing pack expansions.
65
+ if (tupleType.containsPackExpansionType ())
66
+ return 1 ;
67
+
60
68
unsigned count = 0 ;
61
69
for (auto eltType : tupleType.getElementTypes ())
62
70
count += getRValueSize (eltType);
@@ -156,6 +164,10 @@ class ExplodeTupleValue
156
164
}
157
165
158
166
void visitTupleType (CanTupleType tupleFormalType, ManagedValue tuple) {
167
+ // Don't recursively expand tuples containing pack expansions.
168
+ if (tupleFormalType.containsPackExpansionType ())
169
+ return visitType (tupleFormalType, tuple);
170
+
159
171
if (tuple.getType ().isObject ()) {
160
172
return visitObjectTupleType (tupleFormalType, tuple);
161
173
}
@@ -202,6 +214,10 @@ class ImplodeLoadableTupleValue
202
214
}
203
215
204
216
ManagedValue visitTupleType (CanTupleType t, SILLocation l) {
217
+ // Tuples with pack expansions aren't exploded.
218
+ if (t.containsPackExpansionType ())
219
+ return visitType (t, l);
220
+
205
221
SmallVector<ManagedValue, 4 > elts;
206
222
for (auto fieldTy : t.getElementTypes ())
207
223
elts.push_back (this ->visit (fieldTy, l));
@@ -251,6 +267,10 @@ class ImplodeAddressOnlyTuple
251
267
}
252
268
253
269
void visitTupleType (CanTupleType t, Initialization *address, SILLocation l) {
270
+ // Tuples containing pack expansions shouldn't be exploded.
271
+ if (t.containsPackExpansionType ())
272
+ return visitType (t, address, l);
273
+
254
274
assert (address->canSplitIntoTupleElements ());
255
275
llvm::SmallVector<InitializationPtr, 4 > buf;
256
276
auto bufResult = address->splitIntoTupleElements (SGF, l, t, buf);
@@ -272,10 +292,11 @@ class ImplodeAddressOnlyTuple
272
292
273
293
template <ImplodeKind KIND>
274
294
static ManagedValue implodeTupleValues (ArrayRef<ManagedValue> values,
275
- SILGenFunction &SGF, CanType tupleType ,
295
+ SILGenFunction &SGF, CanType type ,
276
296
SILLocation l) {
277
297
// Non-tuples don't need to be imploded.
278
- if (!isa<TupleType>(tupleType)) {
298
+ auto tupleType = dyn_cast<TupleType>(type);
299
+ if (!tupleType || tupleType.containsPackExpansionType ()) {
279
300
assert (values.size () == 1 && " exploded non-tuple value?!" );
280
301
return ImplodeLoadableTupleValue<KIND>::getValue (SGF, values[0 ], l);
281
302
}
@@ -289,13 +310,13 @@ static ManagedValue implodeTupleValues(ArrayRef<ManagedValue> values,
289
310
" address-only values are always managed!" );
290
311
auto buffer = SGF.emitTemporary (l, TL);
291
312
ImplodeAddressOnlyTuple<KIND>(values, SGF)
292
- .visit (tupleType, buffer.get (), l);
313
+ .visitTupleType (tupleType, buffer.get (), l);
293
314
return buffer->getManagedAddress ();
294
315
}
295
316
296
317
// To implode loadable tuples, we just need to combine the elements with
297
318
// TupleInsts.
298
- return ImplodeLoadableTupleValue<KIND>(values, SGF).visit (tupleType, l);
319
+ return ImplodeLoadableTupleValue<KIND>(values, SGF).visitTupleType (tupleType, l);
299
320
}
300
321
301
322
// / Perform a copy or init operation from an array of ManagedValue (from an
@@ -321,7 +342,7 @@ static void copyOrInitValuesInto(Initialization *init,
321
342
322
343
// If the element has non-tuple type, just serve it up to the initialization.
323
344
auto tupleType = dyn_cast<TupleType>(type);
324
- if (!tupleType) {
345
+ if (!tupleType || tupleType. containsPackExpansionType () ) {
325
346
// We take the first value.
326
347
ManagedValue result = values[0 ];
327
348
values = values.slice (1 );
@@ -373,7 +394,7 @@ LLVM_ATTRIBUTE_UNUSED
373
394
static unsigned
374
395
expectedExplosionSize (CanType type) {
375
396
auto tuple = dyn_cast<TupleType>(type);
376
- if (!tuple)
397
+ if (!tuple || tuple. containsPackExpansionType () )
377
398
return 1 ;
378
399
unsigned total = 0 ;
379
400
for (unsigned i = 0 ; i < tuple->getNumElements (); ++i) {
@@ -545,7 +566,8 @@ static void assignRecursive(SILGenFunction &SGF, SILLocation loc,
545
566
CanType type, ArrayRef<ManagedValue> &srcValues,
546
567
SILValue destAddr) {
547
568
// Recurse into tuples.
548
- if (auto srcTupleType = dyn_cast<TupleType>(type)) {
569
+ auto srcTupleType = dyn_cast<TupleType>(type);
570
+ if (srcTupleType && !srcTupleType.containsPackExpansionType ()) {
549
571
assert (destAddr->getType ().castTo <TupleType>()->getNumElements ()
550
572
== srcTupleType->getNumElements ());
551
573
for (auto eltIndex : indices (srcTupleType.getElementTypes ())) {
@@ -651,10 +673,16 @@ RValue RValue::extractElement(unsigned n) && {
651
673
return element;
652
674
}
653
675
676
+ // This is implementable, but we can do it lazily if we add that kind
677
+ // of projection.
678
+ assert (!tupleTy.containsPackExpansionType () &&
679
+ " can't extract elements from tuples containing pack expansions "
680
+ " right now" );
681
+
654
682
auto range = getElementRange (tupleTy, n);
655
683
unsigned from = range.first , to = range.second ;
656
684
657
- CanType eltType = cast<TupleType>(type) .getElementType (n);
685
+ CanType eltType = tupleTy .getElementType (n);
658
686
RValue element (nullptr , llvm::makeArrayRef (values).slice (from, to - from), eltType);
659
687
makeUsed ();
660
688
return element;
@@ -674,6 +702,12 @@ void RValue::extractElements(SmallVectorImpl<RValue> &elements) && {
674
702
return ;
675
703
}
676
704
705
+ // This is implementable, but we can do it lazily if we add that kind
706
+ // of decomposition.
707
+ assert (!tupleTy.containsPackExpansionType () &&
708
+ " can't extract elements from tuples containing pack expansions "
709
+ " right now" );
710
+
677
711
unsigned from = 0 ;
678
712
for (auto eltType : tupleTy.getElementTypes ()) {
679
713
unsigned to = from + getRValueSize (eltType);
0 commit comments