Skip to content

Commit f457a7e

Browse files
committed
[CSGen] Detect and diagnose invalid pack expansion expressions
Detect that pack expansion expression doesn't have any pack references during constraint generation. Resolves: rdar://107835215 (cherry picked from commit bff6a89)
1 parent f45654b commit f457a7e

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

lib/Sema/CSFix.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2759,7 +2759,8 @@ DestructureTupleToMatchPackExpansionParameter::create(
27592759

27602760
bool AllowValueExpansionWithoutPackReferences::diagnose(
27612761
const Solution &solution, bool asNote) const {
2762-
return false;
2762+
ValuePackExpansionWithoutPackReferences failure(solution, getLocator());
2763+
return failure.diagnose(asNote);
27632764
}
27642765

27652766
AllowValueExpansionWithoutPackReferences *

lib/Sema/CSGen.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3080,6 +3080,12 @@ namespace {
30803080
// pack expansion expression through the shape type variable.
30813081
SmallVector<ASTNode, 2> expandedPacks;
30823082
expr->getExpandedPacks(expandedPacks);
3083+
3084+
if (expandedPacks.empty()) {
3085+
(void)CS.recordFix(AllowValueExpansionWithoutPackReferences::create(
3086+
CS, CS.getConstraintLocator(expr)));
3087+
}
3088+
30833089
for (auto pack : expandedPacks) {
30843090
Type packType;
30853091
if (auto *elementExpr = getAsExpr<PackElementExpr>(pack)) {

test/Constraints/pack-expansion-expressions.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,26 @@ do {
457457
// expected-error@-1 {{pack reference 'each T' can only appear in pack expansion}}
458458
}
459459
}
460+
461+
// rdar://107835215 - failed to produce a diagnostic for invalid pack expansion expression
462+
do {
463+
func test1(x: Int) {
464+
repeat x
465+
// expected-error@-1:5 {{value pack expansion must contain at least one pack reference}}
466+
}
467+
468+
func test2<T: Numeric>(_ x: T) {
469+
repeat print(x * 2)
470+
// expected-error@-1:5 {{value pack expansion must contain at least one pack reference}}
471+
}
472+
473+
struct S<T> {
474+
init(_: T) {}
475+
}
476+
477+
func test<each T>(x: repeat each T, y: Int) {
478+
func f<each A, each B>(_: repeat each A, y: repeat each B) {}
479+
f(repeat each x, y: repeat [S(y)])
480+
// expected-error@-1:25 {{value pack expansion must contain at least one pack reference}}
481+
}
482+
}

0 commit comments

Comments
 (0)