Skip to content

Commit 0e99f9c

Browse files
committed
[Variadic Generics] require pack ident type within a pack expansion to form a pack reference
1 parent 8738c81 commit 0e99f9c

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5216,6 +5216,9 @@ ERROR(pack_reference_outside_expansion,none,
52165216
ERROR(each_non_pack,none,
52175217
"'each' cannot be applied to non-pack type %0",
52185218
(Type))
5219+
ERROR(pack_expansion_missing_pack_reference,none,
5220+
"pack expansion %0 must specify a pack reference",
5221+
(TypeRepr*))
52195222
ERROR(tuple_duplicate_label,none,
52205223
"cannot create a tuple with a duplicate element label", ())
52215224
ERROR(multiple_ellipsis_in_tuple,none,

lib/Sema/TypeCheckType.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3803,6 +3803,14 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
38033803
// The base component uses unqualified lookup.
38043804
result = resolveUnqualifiedIdentTypeRepr(resolution.withOptions(options),
38053805
genericParams, identBase);
3806+
3807+
if (result && result->isParameterPack() &&
3808+
options.contains(TypeResolutionFlags::AllowPackReferences) &&
3809+
!options.contains(TypeResolutionFlags::FromPackReference)) {
3810+
diagnose(repr->getLoc(), diag::pack_expansion_missing_pack_reference,
3811+
repr);
3812+
return ErrorType::get(result);
3813+
}
38063814
} else {
38073815
result = resolveType(baseComp, options);
38083816
}
@@ -4265,6 +4273,7 @@ NeverNullType TypeResolver::resolvePackExpansionType(PackExpansionTypeRepr *repr
42654273
NeverNullType TypeResolver::resolvePackReference(PackReferenceTypeRepr *repr,
42664274
TypeResolutionOptions options) {
42674275
auto &ctx = getASTContext();
4276+
options |= TypeResolutionFlags::FromPackReference;
42684277
auto packReference = resolveType(repr->getPackType(), options);
42694278

42704279
// If we already failed, don't diagnose again.

lib/Sema/TypeCheckType.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ enum class TypeResolutionFlags : uint16_t {
7676
/// Pack references are only allowed inside pack expansions
7777
/// and in generic requirements.
7878
AllowPackReferences = 1 << 11,
79+
80+
/// Whether this is a resolution based on a pack reference.
81+
FromPackReference = 1 << 12,
7982
};
8083

8184
/// Type resolution contexts that require special handling.

test/Constraints/pack-expansion-expressions.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,19 @@ func sameShapeDiagnostics<T..., U...>(t: repeat each T, u: repeat each U) {
7777
_ = repeat Array<(each T, each U)>() // expected-error {{pack expansion requires that 'U' and 'T' have the same shape}}
7878
_ = repeat (Array<each T>(), each u) // expected-error {{pack expansion requires that 'U' and 'T' have the same shape}}
7979
}
80+
81+
func returnPackExpansionType<T...>(_ t: repeat each T) -> repeat each T { // expected-error {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
82+
fatalError()
83+
}
84+
85+
func returnEachPackReference<T...>(_ t: repeat each T) -> each T { // expected-error {{pack reference 'T' can only appear in pack expansion or generic requirement}}
86+
fatalError()
87+
}
88+
89+
func returnRepeatTuple<T...>(_ t: repeat each T) -> (repeat T) { // expected-error {{pack expansion 'T' must specify a pack reference}}
90+
fatalError()
91+
}
92+
93+
func paremeterAsPackTypeWithoutExpansion<T...>(_ t: T) -> repeat each T { // expected-error {{variadic expansion 'T' cannot appear outside of a function parameter list, function result, tuple element or generic argument list}}
94+
fatalError()
95+
}

0 commit comments

Comments
 (0)