Skip to content

Commit 7b586d2

Browse files
committed
[Type Resolution] Only allow each applied directly to a type parameter pack.
1 parent c27e2c7 commit 7b586d2

12 files changed

+51
-41
lines changed

include/swift/AST/Types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,10 @@ class alignas(1 << TypeAlignInBits) TypeBase
769769
/// include type parameters in nested positions e.g. \c X<T...>.
770770
bool isParameterPack();
771771

772+
/// Determine whether this type is directly a type parameter pack, which
773+
/// can only be a GenericTypeParamType.
774+
bool isRootParameterPack();
775+
772776
/// Determine whether this type can dynamically be an optional type.
773777
///
774778
/// \param includeExistential Whether an existential type should be considered

lib/AST/ParameterPack.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ bool TypeBase::isParameterPack() {
186186
while (auto *memberTy = t->getAs<DependentMemberType>())
187187
t = memberTy->getBase();
188188

189+
return t->isRootParameterPack();
190+
}
191+
192+
bool TypeBase::isRootParameterPack() {
193+
Type t(this);
194+
189195
return t->is<GenericTypeParamType>() &&
190196
t->castTo<GenericTypeParamType>()->isParameterPack();
191197
}

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4676,7 +4676,7 @@ NeverNullType TypeResolver::resolvePackElement(PackElementTypeRepr *repr,
46764676
if (packReference->hasError())
46774677
return ErrorType::get(ctx);
46784678

4679-
if (!packReference->isParameterPack()) {
4679+
if (!packReference->isRootParameterPack()) {
46804680
auto diag =
46814681
ctx.Diags.diagnose(repr->getLoc(), diag::each_non_pack, packReference);
46824682
bool addEachFixitApplied = false;

test/Constraints/pack-expansion-expressions.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extension P {
5959

6060

6161
func outerArchetype<each T, U>(t: repeat each T, u: U) where repeat each T: P {
62-
let _: (repeat (each T.A, U)) = (repeat ((each t).value, u))
62+
let _: (repeat ((each T).A, U)) = (repeat ((each t).value, u))
6363
}
6464

6565
func sameElement<each T, U>(t: repeat each T, u: U) where repeat each T: P, repeat each T == U {
@@ -478,11 +478,11 @@ do {
478478

479479
// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without a type annotation`
480480
do {
481-
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat each T.A) {
481+
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
482482
return (repeat (each value).makeA()) // Ok
483483
}
484484

485-
func test_misplaced_each<each T: P>(_ value: repeat each T) -> (repeat each T.A) {
485+
func test_misplaced_each<each T: P>(_ value: repeat each T) -> (repeat (each T).A) {
486486
return (repeat each value.makeA())
487487
// expected-error@-1 {{value pack 'each T' must be referenced with 'each'}} {{25-25=(each }} {{30-30=)}}
488488
}

test/IRGen/bind_element_archetype.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public protocol Q {
88

99
public func f<T: P>(_: T) {}
1010

11-
public func foo1<each T: Q>(t: repeat each T, u: repeat each T.A) {
11+
public func foo1<each T: Q>(t: repeat each T, u: repeat (each T).A) {
1212
repeat f(each u)
1313
}
1414

test/IRGen/run_variadic_generics.sil

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -626,18 +626,18 @@ entry(%intIndex : $Builtin.Word):
626626
return %t : $()
627627
}
628628

629-
sil @unwrap_from_PA : $<each T_1 : PA where repeat each T_1.A : P> (Builtin.Word) -> () {
629+
sil @unwrap_from_PA : $<each T_1 : PA where repeat (each T_1).A : P> (Builtin.Word) -> () {
630630
entry(%intIndex : $Builtin.Word):
631631
%direct_access_from_parameter_with_conformance = function_ref @direct_access_from_parameter_with_conformance : $@convention(thin) <each T_1: P> (Builtin.Word) -> ()
632-
apply %direct_access_from_parameter_with_conformance<Pack{repeat GenFwdP<each T_1.A>}>(%intIndex) : $@convention(thin) <each T_1: P> (Builtin.Word) -> ()
632+
apply %direct_access_from_parameter_with_conformance<Pack{repeat GenFwdP<(each T_1).A>}>(%intIndex) : $@convention(thin) <each T_1: P> (Builtin.Word) -> ()
633633
%t = tuple ()
634634
return %t : $()
635635
}
636636

637637
sil @extract_associatedtype_with_conformance : $<each T_1 : P> (Builtin.Word) -> () {
638638
entry(%intIndex : $Builtin.Word):
639639
%innerIndex = dynamic_pack_index %intIndex of $Pack{repeat each T_1}
640-
%token = open_pack_element %innerIndex of <each U_1 : PA where repeat each U_1.A : P> at <Pack{repeat GenAssocPA<GenFwdP<each T_1>>}>, shape $U_1, uuid "01234567-89AB-CDEF-0123-000000000005"
640+
%token = open_pack_element %innerIndex of <each U_1 : PA where repeat (each U_1).A : P> at <Pack{repeat GenAssocPA<GenFwdP<each T_1>>}>, shape $U_1, uuid "01234567-89AB-CDEF-0123-000000000005"
641641
%metatype_1 = metatype $@thick (@pack_element("01234567-89AB-CDEF-0123-000000000005") U_1).Type
642642
%printGenericType = function_ref @printGenericType : $@convention(thin) <T> (@thick T.Type) -> ()
643643
apply %printGenericType<(@pack_element("01234567-89AB-CDEF-0123-000000000005") U_1)>(%metatype_1) : $@convention(thin) <T> (@thick T.Type) -> ()
@@ -653,7 +653,7 @@ sil @extract_associatedtype_with_conformance2 : $<each T_1 : P, Tee : P, each T_
653653
entry(%intIndex : $Builtin.Word):
654654
%innerIndex = dynamic_pack_index %intIndex of $Pack{repeat GenAssocPA<GenAssocPA<GenAssocPA<GenFwdP<each T_1>>>>, repeat GenAssocPA<GenAssocPA<GenAssocPA<GenFwdP<each T_1>>>>}
655655
%token = open_pack_element %innerIndex
656-
of <each U_1 : PA, Ewe : PA, each U_2 : PA where repeat each U_1.A : PA, repeat each U_1.A.A : PA, repeat each U_1.A.A.A : P, Ewe.A : PA, Ewe.A.A : PA, Ewe.A.A.A : P, repeat each U_2.A : PA, repeat each U_2.A.A : PA, repeat each U_2.A.A.A : P, (repeat (each U_1, each U_2)): Any>
656+
of <each U_1 : PA, Ewe : PA, each U_2 : PA where repeat (each U_1).A : PA, repeat (each U_1).A.A : PA, repeat (each U_1).A.A.A : P, Ewe.A : PA, Ewe.A.A : PA, Ewe.A.A.A : P, repeat (each U_2).A : PA, repeat (each U_2).A.A : PA, repeat (each U_2).A.A.A : P, (repeat (each U_1, each U_2)): Any>
657657
at <
658658
Pack{repeat GenAssocPA<GenAssocPA<GenAssocPA<GenFwdP<each T_1>>>>, repeat GenAssocPA<GenAssocPA<GenAssocPA<GenFwdP<each T_1>>>>},
659659
GenAssocPA<GenAssocPA<GenAssocPA<GenFwdP<Tee>>>>,

test/IRGen/variadic_generic_captures.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ public func has_witness_table_pack<each T: Sequence>(t: repeat each T) -> () ->
6262
}
6363

6464
public func has_witness_table_pack2<each T: Sequence>(t: repeat each T) -> () -> ()
65-
where repeat each T.Element: Sequence {
65+
where repeat (each T).Element: Sequence {
6666
return { _ = (repeat (each T).Element.Element).self }
6767
}

test/IRGen/variadic_generic_functions.sil

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ sil @fc : $<each T : P> () -> () {}
7272
// CHECK-SAME: ptr %"each T.PA",
7373
// CHECK-SAME: ptr %"each T.A.P")
7474
// CHECK: call swiftcc void @f1c([[INT]] %0, ptr %"each T", ptr %"each T.PA", ptr %"each T.A.P")
75-
sil @f1 : $<each T : PA where repeat each T.A : P> () -> () {
76-
%f1c = function_ref @f1c : $@convention(thin) <each T : PA where repeat each T.A : P> () -> ()
77-
apply %f1c<Pack{repeat each T}>() : $@convention(thin) <each T : PA where repeat each T.A : P> () -> ()
75+
sil @f1 : $<each T : PA where repeat (each T).A : P> () -> () {
76+
%f1c = function_ref @f1c : $@convention(thin) <each T : PA where repeat (each T).A : P> () -> ()
77+
apply %f1c<Pack{repeat each T}>() : $@convention(thin) <each T : PA where repeat (each T).A : P> () -> ()
7878
%ret = tuple ()
7979
return %ret : $()
8080
}
8181

82-
sil @f1c : $<each T : PA where repeat each T.A : P> () -> () {}
82+
sil @f1c : $<each T : PA where repeat (each T).A : P> () -> () {}
8383

8484
// Construct associatedtype metadata pack, forward root wtable pack.
8585
// CHECK-LABEL: define {{.*}}@associatedtype_with_added_conformance(
@@ -92,9 +92,9 @@ sil @f1c : $<each T : PA where repeat each T.A : P> () -> () {}
9292
// CHECK-SAME: [[INT]] [[SHAPE]],
9393
// CHECK-SAME: ptr [[ASSOCIATEDTYPES]],
9494
// CHECK-SAME: ptr [[ASSOCIATEDTYPES_CONFORMANCES_TO_Q]])
95-
sil @associatedtype_with_added_conformance : $<each T : PA where repeat each T.A : Q> () -> () {
95+
sil @associatedtype_with_added_conformance : $<each T : PA where repeat (each T).A : Q> () -> () {
9696
%callee = function_ref @associatedtype_with_added_conformance_callee : $@convention(thin) <each T : Q> () -> ()
97-
apply %callee<Pack{repeat each T.A}>() : $@convention(thin) <each T : Q> () -> ()
97+
apply %callee<Pack{repeat (each T).A}>() : $@convention(thin) <each T : Q> () -> ()
9898
%ret = tuple ()
9999
return %ret : $()
100100
}
@@ -112,9 +112,9 @@ sil @associatedtype_with_added_conformance_callee : $<each T : Q> () -> () {}
112112
// CHECK-SAME: [[INT]] [[SHAPE]],
113113
// CHECK-SAME: ptr [[ASSOCIATEDTYPES]],
114114
// CHECK-SAME: ptr [[ASSOCIATEDTYPES_CONFORMANCES_TO_Q]])
115-
sil @associatedtype_with_added_conformance_2 : $<each T : PA where repeat each T.A : QA, repeat each T.A.A : R> () -> () {
115+
sil @associatedtype_with_added_conformance_2 : $<each T : PA where repeat (each T).A : QA, repeat (each T).A.A : R> () -> () {
116116
%j = function_ref @associatedtype_with_added_conformance_2_callee : $@convention(thin) <each T : R> () -> ()
117-
apply %j<Pack{repeat each T.A.A}>() : $@convention(thin) <each T : R> () -> ()
117+
apply %j<Pack{repeat (each T).A.A}>() : $@convention(thin) <each T : R> () -> ()
118118
%ret = tuple ()
119119
return %ret : $()
120120
}
@@ -157,13 +157,13 @@ sil @associatedtype_with_forwarded_conformance_1_callee : $<each T : Q> () -> ()
157157
// CHECK-SAME: ptr [[GEN1_CONFORMANCES_TO_PA]],
158158
// CHECK-SAME: ptr %"each T.A.Q")
159159
// CHECK: call void @llvm.stackrestore(ptr [[STORED_STACK_LOC]])
160-
sil @generictype_with_forwarded_conformance_2 : $<each T : PA where repeat each T.A : Q>() -> () {
161-
%callee = function_ref @generictype_with_forwarded_conformance_2_callee : $@convention(thin) <each T : PA where repeat each T.A : Q> () -> ()
162-
apply %callee<Pack{repeat Gen1<each T>}>() : $@convention(thin) <each T : PA where repeat each T.A : Q> () -> ()
160+
sil @generictype_with_forwarded_conformance_2 : $<each T : PA where repeat (each T).A : Q>() -> () {
161+
%callee = function_ref @generictype_with_forwarded_conformance_2_callee : $@convention(thin) <each T : PA where repeat (each T).A : Q> () -> ()
162+
apply %callee<Pack{repeat Gen1<each T>}>() : $@convention(thin) <each T : PA where repeat (each T).A : Q> () -> ()
163163
%ret = tuple ()
164164
return %ret : $()
165165
}
166-
sil @generictype_with_forwarded_conformance_2_callee : $<each T : PA where repeat each T.A : Q> () -> () {}
166+
sil @generictype_with_forwarded_conformance_2_callee : $<each T : PA where repeat (each T).A : Q> () -> () {}
167167

168168
// Construct a pack of generic types of generic types which "forward" conformance to a protocol with an associatedtype which itself conforms to a protocol.
169169
// CHECK-LABEL: define {{.*}}@generic_with_forwarded_conformance_3(
@@ -180,12 +180,12 @@ sil @generictype_with_forwarded_conformance_2_callee : $<each T : PA where repea
180180
// CHECK-SAME: ptr [[GEN1_GEN1_CONFORMANCES_TO_PA]],
181181
// CHECK-SAME: ptr %"each T.A.Q")
182182
// CHECK: call void @llvm.stackrestore(ptr [[STORED_STACK_LOC]])
183-
sil @generic_with_forwarded_conformance_3 : $<each T : PA where repeat each T.A : Q> () -> () {
184-
%callee = function_ref @generic_with_forwarded_conformance_3_callee : $@convention(thin) <each T : PA where repeat each T.A : Q> () -> ()
185-
apply %callee<Pack{repeat Gen1<Gen1<each T>>}>() : $@convention(thin) <each T : PA where repeat each T.A : Q> () -> ()
183+
sil @generic_with_forwarded_conformance_3 : $<each T : PA where repeat (each T).A : Q> () -> () {
184+
%callee = function_ref @generic_with_forwarded_conformance_3_callee : $@convention(thin) <each T : PA where repeat (each T).A : Q> () -> ()
185+
apply %callee<Pack{repeat Gen1<Gen1<each T>>}>() : $@convention(thin) <each T : PA where repeat (each T).A : Q> () -> ()
186186
%ret = tuple ()
187187
return %ret : $()
188188
}
189-
sil @generic_with_forwarded_conformance_3_callee : $<each T : PA where repeat each T.A : Q> () -> () {
189+
sil @generic_with_forwarded_conformance_3_callee : $<each T : PA where repeat (each T).A : Q> () -> () {
190190
}
191191

test/Interpreter/variadic_generic_conformances.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,29 @@ extension Int: Q {}
5656
extension Bool: Q {}
5757

5858
protocol HasPackRequirements {
59-
func doStuff1<each T: Q>(_ value: repeat each T) -> (repeat each T.A)
60-
func doStuff2<each T: Q>(_ value: repeat each T) -> (repeat each T.A)
59+
func doStuff1<each T: Q>(_ value: repeat each T) -> (repeat (each T).A)
60+
func doStuff2<each T: Q>(_ value: repeat each T) -> (repeat (each T).A)
6161
}
6262

6363
extension HasPackRequirements {
64-
func doStuff1<each T: Q>(_ value: repeat each T) -> (repeat each T.A) {
64+
func doStuff1<each T: Q>(_ value: repeat each T) -> (repeat (each T).A) {
6565
return (repeat (each value).makeA())
6666
}
6767
}
6868

6969
struct ConformsPackRequirements: HasPackRequirements {
70-
func doStuff2<each T: Q>(_ value: repeat each T) -> (repeat each T.A) {
70+
func doStuff2<each T: Q>(_ value: repeat each T) -> (repeat (each T).A) {
7171
return (repeat (each value).makeA())
7272
}
7373
}
7474

7575
func testPackRequirements1<T: HasPackRequirements, each U: Q>(_ t: T, _ u: repeat each U)
76-
-> (repeat each U.A) {
76+
-> (repeat (each U).A) {
7777
return t.doStuff1(repeat each u)
7878
}
7979

8080
func testPackRequirements2<T: HasPackRequirements, each U: Q>(_ t: T, _ u: repeat each U)
81-
-> (repeat each U.A) {
81+
-> (repeat (each U).A) {
8282
return t.doStuff2(repeat each u)
8383
}
8484

test/Interpreter/variadic_generic_type_witnesses.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ struct G<each T> {}
2020

2121
struct TupleWitnesses<each T: Sequence>: P {
2222
typealias A = (Bool, repeat each T)
23-
typealias B = (repeat each T.Element, x: Bool)
24-
typealias C = (x: Bool, repeat H<each T.Element>)
23+
typealias B = (repeat (each T).Element, x: Bool)
24+
typealias C = (x: Bool, repeat H<(each T).Element>)
2525
}
2626

2727
struct SingletonTupleWitnesses<each T>: P {
@@ -32,14 +32,14 @@ struct SingletonTupleWitnesses<each T>: P {
3232

3333
struct FunctionWitnesses<each T: Sequence>: P {
3434
typealias A = (Bool, repeat each T) -> ()
35-
typealias B = (repeat each T.Element, Bool) -> ()
36-
typealias C = (Bool, repeat H<each T.Element>) -> ()
35+
typealias B = (repeat (each T).Element, Bool) -> ()
36+
typealias C = (Bool, repeat H<(each T).Element>) -> ()
3737
}
3838

3939
struct NominalWitnesses<each T: Sequence>: P {
4040
typealias A = G<Bool, repeat each T>
41-
typealias B = G<repeat each T.Element, Bool>
42-
typealias C = G<Bool, repeat H<each T.Element>>
41+
typealias B = G<repeat (each T).Element, Bool>
42+
typealias C = G<Bool, repeat H<(each T).Element>>
4343
}
4444

4545
func getA<T: P>(_: T.Type) -> Any.Type {

0 commit comments

Comments
 (0)