Skip to content

Commit 33f03f7

Browse files
Merge pull request #78434 from AnthonyLatsis/each-pack
Sema: Do better at diagnosing missing `each`
2 parents 57657c6 + 4924621 commit 33f03f7

File tree

2 files changed

+81
-65
lines changed

2 files changed

+81
-65
lines changed

lib/Sema/CSGen.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -794,16 +794,13 @@ namespace {
794794
// value packs cannot be referenced without `each` immediately
795795
// preceding them.
796796
if (auto *expansionType = knownType->getAs<PackExpansionType>()) {
797-
if (auto *parentExpansionExpr = getParentPackExpansionExpr(E);
798-
parentExpansionExpr &&
799-
!isExpr<PackElementExpr>(CS.getParentExpr(E))) {
797+
if (!isExpr<PackElementExpr>(CS.getParentExpr(E))) {
800798
auto packType = expansionType->getPatternType();
801799
(void)CS.recordFix(
802800
IgnoreMissingEachKeyword::create(CS, packType, locator));
803-
auto eltType =
804-
openPackElement(packType, locator, parentExpansionExpr);
805-
CS.setType(E, eltType);
806-
return eltType;
801+
802+
return openPackElement(packType, locator,
803+
getParentPackExpansionExpr(E));
807804
}
808805
}
809806
}

test/Constraints/pack-expansion-expressions.swift

Lines changed: 77 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -263,27 +263,6 @@ func forwardFunctionPack<each T>(functions: repeat (each T) -> Bool) {
263263
takesFunctionPack(functions: repeat each functions)
264264
}
265265

266-
func packOutsideExpansion<each T>(_ t: repeat each T) {
267-
_ = t
268-
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
269-
270-
forward(t)
271-
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
272-
273-
_ = each t
274-
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
275-
276-
forward(each t)
277-
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
278-
279-
let tuple = (repeat each t)
280-
281-
_ = tuple
282-
283-
_ = each tuple
284-
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
285-
}
286-
287266
func identity<T>(_ t: T) -> T { t }
288267
func concrete(_: Int) {}
289268

@@ -474,18 +453,6 @@ do {
474453
}
475454
}
476455

477-
// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without a type annotation`
478-
do {
479-
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
480-
return (repeat (each value).makeA()) // Ok
481-
}
482-
483-
func test_misplaced_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
484-
return (repeat each value.makeA())
485-
// expected-error@-1 {{value pack 'each T' must be referenced with 'each'}} {{25-25=(each }} {{30-30=)}}
486-
}
487-
}
488-
489456
// rdar://107835215 - failed to produce a diagnostic for invalid pack expansion expression
490457
do {
491458
func test1(x: Int) {
@@ -509,19 +476,6 @@ do {
509476
}
510477
}
511478

512-
// missing 'each' keyword before value pack references
513-
do {
514-
func overloaded<each U>(_: String, _: repeat each U) -> Int { 42 }
515-
func overloaded<each T>(_: Int, _ b: repeat each T) -> (repeat each T) {
516-
fatalError()
517-
}
518-
519-
func test<each T>(v: repeat each T) {
520-
_ = (repeat overloaded(42, v)) // expected-error {{value pack 'each T' must be referenced with 'each'}} {{32-32=each }}
521-
_ = (repeat overloaded(42, each v)) // Ok
522-
}
523-
}
524-
525479
// rdar://108904190 - top-level 'repeat' not allowed in single-expression closures
526480
func test_pack_expansion_to_void_conv_for_closure_result<each T>(x: repeat each T) {
527481
let _: () -> Void = { repeat print(each x) } // Ok
@@ -715,18 +669,6 @@ do {
715669
}
716670
}
717671

718-
// rdar://110847476 - unrelated assignment and raw representable diagnostics
719-
do {
720-
struct Test<each Base: AsyncSequence> {
721-
let base: (repeat each Base)
722-
723-
init(base: repeat each Base) {
724-
self.base = base
725-
// expected-error@-1 {{pack reference 'each Base' can only appear in pack expansion}}
726-
}
727-
}
728-
}
729-
730672
// Pack Iteration
731673
do {
732674
func test<each T>(_ t: repeat each T) {
@@ -765,3 +707,80 @@ func butt<T>(x: T) {}
765707
func rump<each T>(x: repeat each T) {
766708
let x = (repeat { butt(each x) }()) // expected-error {{missing argument label 'x:' in call}}
767709
}
710+
711+
// Placement of `each` in expressions.
712+
do {
713+
do {
714+
func overload<each U>(_: String, _: repeat each U) -> Int {}
715+
func overload<each T>(_: Int, _ b: repeat each T) -> (repeat each T) {}
716+
717+
func test<each T>(
718+
t: repeat each T,
719+
t2: repeat (each T)?,
720+
t3: repeat () -> each T
721+
) {
722+
_ = t
723+
// expected-error@-1{{value pack 'each T' must be referenced with 'each'}}
724+
725+
forward(t)
726+
// expected-error@-1{{value pack 'each T' must be referenced with 'each'}}
727+
728+
_ = each t
729+
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
730+
731+
forward(each t)
732+
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
733+
734+
let tuple = (repeat each t)
735+
_ = tuple
736+
_ = each tuple
737+
// expected-error@-1{{pack reference 'each T' can only appear in pack expansion}}
738+
739+
// https://github.com/swiftlang/swift/issues/78393
740+
let _ = (t2)
741+
// expected-error@-1{{value pack '(each T)?' must be referenced with 'each'}}
742+
let _ = t3
743+
// expected-error@-1{{value pack '() -> each T' must be referenced with 'each'}}
744+
745+
let _ = (repeat overload(42, t)) // expected-error {{value pack 'each T' must be referenced with 'each'}} {{36-36=each }}
746+
let _ = (repeat overload(42, each t)) // Ok
747+
}
748+
}
749+
750+
// FIXME: https://github.com/swiftlang/swift/issues/78426
751+
do {
752+
func f<each T>(_: (repeat each T) -> (repeat each T)) {}
753+
// expected-error@+2 {{cannot infer type of closure parameter 'x' without a type annotation}}
754+
// expected-error@+1 {{cannot convert value of type '(Int, Int)' to closure result type '(_: _)'}}
755+
f { x in
756+
// Once this issue is fixed, verify that 'x' below is diagnosed correctly.
757+
// If it is not, please reopen https://github.com/swiftlang/swift/issues/78393.
758+
let _ = x
759+
return (1, 2)
760+
}
761+
}
762+
763+
// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without a type annotation`
764+
do {
765+
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
766+
return (repeat (each value).makeA()) // Ok
767+
}
768+
769+
func test_misplaced_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
770+
return (repeat each value.makeA())
771+
// expected-error@-1 {{value pack 'each T' must be referenced with 'each'}} {{27-27=(each }} {{32-32=)}}
772+
}
773+
}
774+
775+
// rdar://110847476 - unrelated assignment and raw representable diagnostics
776+
do {
777+
struct Test<each Base: AsyncSequence> {
778+
let base: (repeat each Base)
779+
780+
init(base: repeat each Base) {
781+
self.base = base
782+
// expected-error@-1 {{value pack 'each Base' must be referenced with 'each'}}
783+
}
784+
}
785+
}
786+
}

0 commit comments

Comments
 (0)