Skip to content

Commit ab47063

Browse files
committed
Produce Pack Expansion Types for Polyvariadic Functions
Also begin resolving (T...) as a pack expansion.
1 parent b3f70c9 commit ab47063

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2110,7 +2110,14 @@ static Type validateParameterType(ParamDecl *decl) {
21102110
}
21112111

21122112
if (decl->isVariadic()) {
2113-
Ty = VariadicSequenceType::get(Ty);
2113+
// Handle the monovariadic/polyvariadic interface type split.
2114+
if (Ty->hasTypeSequence()) {
2115+
// Polyvariadic types (T...) for <T...> resolve to pack expansions.
2116+
Ty = PackExpansionType::get(Ty);
2117+
} else {
2118+
// Monovariadic types (T...) for <T> resolve to [T].
2119+
Ty = VariadicSequenceType::get(Ty);
2120+
}
21142121
if (!ctx.getArrayDecl()) {
21152122
ctx.Diags.diagnose(decl->getTypeRepr()->getLoc(),
21162123
diag::sugar_type_not_found, 0);

lib/Sema/TypeCheckType.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3559,12 +3559,31 @@ NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr,
35593559
elementOptions = elementOptions.withoutContext(true);
35603560
}
35613561

3562-
// Variadic tuples are not permitted.
35633562
bool complained = false;
35643563
if (repr->hasEllipsis()) {
3565-
diagnose(repr->getEllipsisLoc(), diag::tuple_ellipsis);
3566-
repr->removeEllipsis();
3567-
complained = true;
3564+
if (repr->getNumElements() == 1 && !repr->hasElementNames()) {
3565+
// This is probably a pack expansion. Try to resolve the pattern type.
3566+
auto patternTy = resolveType(repr->getElementType(0), elementOptions);
3567+
if (patternTy->hasError())
3568+
complained = true;
3569+
3570+
// If there's no reference to a variadic generic parameter, complain
3571+
// - the pack won't actually expand to anything meaningful.
3572+
if (!patternTy->hasTypeSequence())
3573+
diagnose(repr->getLoc(), diag::expansion_not_variadic, patternTy)
3574+
.highlight(repr->getParens());
3575+
3576+
return PackExpansionType::get(patternTy);
3577+
} else {
3578+
// Variadic tuples are not permitted.
3579+
//
3580+
// FIXME: We could probably make this work.
3581+
// (T, U, V...) is a reasonable pack expansion to support with a kind of
3582+
// "guaranteed bound" of at least two elements.
3583+
diagnose(repr->getEllipsisLoc(), diag::tuple_ellipsis);
3584+
repr->removeEllipsis();
3585+
complained = true;
3586+
}
35683587
}
35693588

35703589
bool hadError = false;

0 commit comments

Comments
 (0)