Skip to content

Commit 1fa9afc

Browse files
committed
Sema: Allow parameterized existential compositions
1 parent 4338a55 commit 1fa9afc

File tree

5 files changed

+102
-17
lines changed

5 files changed

+102
-17
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6002,11 +6002,7 @@ TypeResolver::resolveCompositionType(CompositionTypeRepr *repr,
60026002
continue;
60036003
}
60046004

6005-
// FIXME: Support compositions involving parameterized protocol types,
6006-
// like 'any Collection<String> & Sendable', etc.
6007-
if (ty->is<ParameterizedProtocolType>() &&
6008-
!options.isConstraintImplicitExistential() &&
6009-
options.getContext() != TypeResolverContext::ExistentialConstraint) {
6005+
if (ty->is<ParameterizedProtocolType>()) {
60106006
checkMember(tyR->getStartLoc(), ty);
60116007
Members.push_back(ty);
60126008
continue;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking
2+
3+
func f1(_ s: any Sequence<Int> & Hashable) -> any Sequence<Int> {
4+
return s
5+
}
6+
7+
func f2(_ s: any Sequence<Int> & Hashable) -> any Hashable {
8+
return s
9+
}
10+
11+
func f3(_ s: any Sequence<Int> & Hashable) -> any Sequence {
12+
return s
13+
}
14+
15+
func f4(_ s: any Sequence<Int> & Hashable) -> any Sequence & Hashable {
16+
return s
17+
}
18+
19+
func f5(_ s: any Sequence<Int> & Hashable) -> any Sequence<Int> & Equatable {
20+
return s
21+
}
22+
23+
func f6(_ s: any Sequence<Int> & Hashable) -> any Sequence<String> & Hashable {
24+
return s // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
25+
}
26+
27+
func f7(_ s: any Sequence<Int> & Hashable) -> any Sequence<String> {
28+
return s // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
29+
}
30+
31+
func f8(_ s: any Collection<Int> & Hashable) -> any Sequence<Int> & Hashable {
32+
return s
33+
}
34+
35+
// https://github.com/swiftlang/swift/issues/71012
36+
37+
protocol A<T> {
38+
associatedtype T
39+
}
40+
protocol B {}
41+
typealias C = A & B
42+
typealias D<T> = A<T> & B
43+
44+
struct Foo: C {
45+
typealias T = Int
46+
}
47+
48+
struct Bar<Value> { // expected-note {{arguments to generic parameter 'Value' ('any C' (aka 'any A & B') and 'any A<Int> & B') are expected to be equal}}
49+
let value: Value
50+
}
51+
52+
struct Baz<U> {
53+
let bar: Bar<any D<U>>
54+
}
55+
56+
func run() {
57+
let foo: any C = Foo()
58+
let bar = Bar(value: foo)
59+
_ = Baz<Int>(bar: bar)
60+
// expected-error@-1 {{cannot convert value of type 'Bar<any C>' (aka 'Bar<any A & B>') to expected argument type 'Bar<any A<Int> & B>'}}
61+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %target-swift-emit-silgen -disable-availability-checking %s | %FileCheck %s
2+
3+
protocol P<A> {
4+
associatedtype A
5+
}
6+
7+
protocol Q<B> {
8+
associatedtype B
9+
}
10+
11+
// All of these should have unique mangling.
12+
func overload(_: any P<Int> & Q<String>) {}
13+
func overload(_: any P<Float> & Q<String>) {}
14+
func overload(_: any P & Q<String>) {}
15+
func overload(_: any P<Int> & Q<Bool>) {}
16+
func overload(_: any P<Float> & Q<Bool>) {}
17+
func overload(_: any P & Q<Bool>) {}
18+
func overload(_: any P<Int> & Q) {}
19+
func overload(_: any P<Float> & Q) {}
20+
func overload(_: any P & Q) {}
21+
func overload(_: any P<Int>) {}
22+
func overload(_: any P<Float>) {}
23+
func overload(_: any P) {}
24+
func overload(_: any Q<Bool>) {}
25+
func overload(_: any Q) {}
26+
27+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_SS1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Int> & Q<String>) -> () {
28+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_SS1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Float> & Q<String>) -> () {
29+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSS1BAaDPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q<String>) -> () {
30+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_Sb1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Int> & Q<Bool>) -> () {
31+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_Sb1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Float> & Q<Bool>) -> () {
32+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSb1BAaDPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q<Bool>) -> () {
33+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P<Int> & Q) -> () {
34+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P<Float> & Q) -> () {
35+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpF : $@convention(thin) (@in_guaranteed any P & Q) -> () {
36+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_pSi1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P<Int>) -> () {
37+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_pSf1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P<Float>) -> () {
38+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_pF : $@convention(thin) (@in_guaranteed any P) -> () {
39+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1Q_pSb1BAaCPRts_XPF : $@convention(thin) (@in_guaranteed any Q<Bool>) -> () {
40+
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1Q_pF : $@convention(thin) (@in_guaranteed any Q) -> () {

test/decl/protocol/existential_member_access/basic.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,6 @@ do {
506506
func invariant11() -> Struct<${type}>.InnerGeneric<Void>
507507
// https://github.com/apple/swift/issues/61934
508508
func invariant12() -> any Sequence<${type}>
509-
// FIXME
510-
// expected-error@+1 {{non-protocol, non-class type 'Sequence<${type}>' cannot be used within a protocol-constrained type}}
511509
func invariant13() -> any P & Sequence<${type}>
512510
func invariant14() -> (any Sequence<${type}>).Type
513511
func invariant15() -> any (P & Class<${type}>).Type

test/type/parameterized_existential.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,6 @@ func typeExpr() {
8282
_ = (any Sequence<Int>).self
8383
}
8484

85-
/// Not supported as a protocol composition term for now
86-
87-
protocol SomeProto {}
88-
89-
func protocolCompositionNotSupported1(_: SomeProto & Sequence<Int>) {}
90-
// expected-error@-1 {{non-protocol, non-class type 'Sequence<Int>' cannot be used within a protocol-constrained type}}
91-
92-
func protocolCompositionNotSupported2(_: any SomeProto & Sequence<Int>) {}
93-
// expected-error@-1 {{non-protocol, non-class type 'Sequence<Int>' cannot be used within a protocol-constrained type}}
94-
9585
func increment(_ n : any Collection<Float>) {
9686
for value in n {
9787
_ = value + 1

0 commit comments

Comments
 (0)