Skip to content

Commit 8caeaa2

Browse files
committed
Sema: Ensure that generic parameters appearing in pack expansion patterns all have the same shape
1 parent 5ee7125 commit 8caeaa2

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5144,6 +5144,10 @@ ERROR(tuple_duplicate_label,none,
51445144
ERROR(multiple_ellipsis_in_tuple,none,
51455145
"only a single element can be variadic", ())
51465146

5147+
ERROR(expansion_not_same_shape,none,
5148+
"variadic expansion %0 requires that %1 and %2 have the same shape",
5149+
(Type, Type, Type))
5150+
51475151
ERROR(enum_element_ellipsis,none,
51485152
"variadic enum cases are not supported", ())
51495153
ERROR(unlabeled_parameter_following_variadic_parameter,none,

lib/Sema/TypeCheckType.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4238,7 +4238,18 @@ NeverNullType TypeResolver::resolvePackExpansionType(PackExpansionTypeRepr *repr
42384238
if (resolution.getStage() == TypeResolutionStage::Interface) {
42394239
auto genericSig = resolution.getGenericSignature();
42404240
auto shapeType = genericSig->getReducedShape(pair.second);
4241-
return PackExpansionType::get(pair.first, shapeType);
4241+
4242+
auto result = PackExpansionType::get(pair.first, shapeType);
4243+
4244+
SmallVector<Type, 2> rootParameterPacks;
4245+
pair.first->getTypeParameterPacks(rootParameterPacks);
4246+
for (auto type : rootParameterPacks) {
4247+
if (!genericSig->haveSameShape(type, shapeType)) {
4248+
ctx.Diags.diagnose(repr->getLoc(), diag::expansion_not_same_shape,
4249+
result, shapeType, type);
4250+
}
4251+
}
4252+
return result;
42424253
}
42434254

42444255
return PackExpansionType::get(pair.first, pair.second);

test/type/pack_expansion.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,17 @@ enum E<T...> {
5050

5151
func withWhereClause<T...>(_ x: T...) where T...: P {}
5252
// expected-error@-1 {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
53+
54+
struct Outer<T...> {
55+
struct Bad<U...> {
56+
typealias Value = ((T, U)...) // expected-error {{variadic expansion '(T, U)...' requires that 'T' and 'U' have the same shape}}
57+
}
58+
59+
struct Good<U...> where ((T, U)...): Any {
60+
typealias Value = ((T, U)...)
61+
}
62+
63+
struct AlsoGood<U...> {
64+
typealias Value = ((T, E<U... >)...)
65+
}
66+
}

0 commit comments

Comments
 (0)