Skip to content

Commit 1e03cdc

Browse files
committed
[AST] PackMacher: Match pack expansion elements pair-wise if pack arity matches
This covers situations like `Pack{repeat each T1, repeat each T2}` vs. `Pack{repeat $T1, repeat $T2}` where type variables are allowed to bind to packs. Resolves: rdar://109539394
1 parent 70e4cf0 commit 1e03cdc

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

include/swift/AST/PackExpansionMatcher.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,23 @@ class TypeListPackMatcher {
186186
}
187187
}
188188

189+
// Both sides have equal number of pack expansion type.
190+
if (lhsElts.size() == rhsElts.size()) {
191+
for (unsigned i = 0, n = lhsElts.size(); i != n; ++i) {
192+
auto lhsType = getElementType(lhsElts[i]);
193+
auto rhsType = getElementType(rhsElts[i]);
194+
195+
if (IsPackExpansionType(lhsType) && IsPackExpansionType(rhsType)) {
196+
pairs.emplace_back(lhsType, rhsType, i, i);
197+
} else {
198+
pairs.clear();
199+
return true;
200+
}
201+
}
202+
203+
return false;
204+
}
205+
189206
// Otherwise, all remaining possibilities are invalid:
190207
// - Neither side has any pack expansions, and they have different lengths.
191208
// - One side has a pack expansion but the other side is too short, eg

test/Constraints/pack-expansion-expressions.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,3 +528,12 @@ func test_pack_expansion_to_void_conv_for_closure_result<each T>(x: repeat each
528528
let _: (Int) -> Void = { repeat ($0, print(each x)) } // expected-warning {{'repeat (Int, ())' is unused}}
529529
let _: (Int, String) -> Void = { ($0, repeat ($1, print(each x))) } // expected-warning {{'(Int, repeat (String, ()))' is unused}}
530530
}
531+
532+
// rdar://109539394 - crash on passing multiple variadic lists to singly variadic callee
533+
do {
534+
func test1<each T>(_: repeat each T) {}
535+
536+
func caller<each T1, each T2>(t1: repeat each T1, t2: repeat each T2) {
537+
test1(repeat each t1, repeat each t2) // Ok
538+
}
539+
}

0 commit comments

Comments
 (0)