Skip to content

Commit 01f7172

Browse files
committed
[Variadic Generics] require pack ident type within a pack expansion to form a pack reference
1 parent fa1f536 commit 01f7172

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5208,6 +5208,9 @@ ERROR(pack_reference_outside_expansion,none,
52085208
ERROR(each_non_pack,none,
52095209
"'each' cannot be applied to non-pack type %0",
52105210
(Type))
5211+
ERROR(pack_expansion_missing_pack_reference,none,
5212+
"pack expansion %0 must specify a pack reference",
5213+
(TypeRepr*))
52115214
ERROR(tuple_duplicate_label,none,
52125215
"cannot create a tuple with a duplicate element label", ())
52135216
ERROR(multiple_ellipsis_in_tuple,none,

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3819,6 +3819,14 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
38193819
// The base component uses unqualified lookup.
38203820
result = resolveUnqualifiedIdentTypeRepr(resolution.withOptions(options),
38213821
genericParams, identBase);
3822+
3823+
if (result && result->isParameterPack() &&
3824+
options.contains(TypeResolutionFlags::FromPackExpansion) &&
3825+
!options.contains(TypeResolutionFlags::FromPackReference)) {
3826+
diagnose(repr->getLoc(), diag::pack_expansion_missing_pack_reference,
3827+
repr);
3828+
return ErrorType::get(result);
3829+
}
38223830
} else {
38233831
result = resolveType(baseComp, options);
38243832
}
@@ -4257,7 +4265,8 @@ NeverNullType TypeResolver::resolvePackExpansionType(PackExpansionTypeRepr *repr
42574265
TypeResolutionOptions options) {
42584266
auto &ctx = getASTContext();
42594267

4260-
auto pair = maybeResolvePackExpansionType(repr, options);
4268+
const auto patternOptions = options | TypeResolutionFlags::FromPackExpansion;
4269+
auto pair = maybeResolvePackExpansionType(repr, patternOptions);
42614270

42624271
if (pair.first->hasError())
42634272
return ErrorType::get(ctx);
@@ -4298,6 +4307,7 @@ NeverNullType TypeResolver::resolvePackExpansionType(PackExpansionTypeRepr *repr
42984307
NeverNullType TypeResolver::resolvePackReference(PackReferenceTypeRepr *repr,
42994308
TypeResolutionOptions options) {
43004309
auto &ctx = getASTContext();
4310+
options |= TypeResolutionFlags::FromPackReference;
43014311
auto packReference = resolveType(repr->getPackType(), options);
43024312

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

lib/Sema/TypeCheckType.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ 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 expansion.
81+
FromPackExpansion = 1 << 12,
82+
83+
/// Whether this is a resolution based on a pack reference.
84+
FromPackReference = 1 << 13,
7985
};
8086

8187
/// 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)