Skip to content

Commit 06e58d2

Browse files
committed
Add tests for parametrized protocol types
1 parent 5ac1fc1 commit 06e58d2

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

test/type/parametrized_protocol.swift

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify -enable-parametrized-protocol-types -disable-availability-checking
2+
3+
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=verify -enable-parametrized-protocol-types -requirement-machine-inferred-signatures=verify -disable-availability-checking 2>&1 | %FileCheck %s
4+
5+
6+
protocol Sequence {
7+
@_primaryAssociatedType associatedtype Element
8+
// expected-note@-1 {{protocol requires nested type 'Element'; do you want to add it?}}
9+
}
10+
11+
struct ConcreteSequence<Element> : Sequence {}
12+
13+
protocol EquatableSequence {
14+
@_primaryAssociatedType associatedtype Element : Equatable
15+
}
16+
17+
struct ConcreteEquatableSequence<Element : Equatable> : EquatableSequence {}
18+
19+
20+
/// Parametrized protocol in protocol inheritance clause
21+
22+
// CHECK-LABEL: parametrized_protocol.(file).IntSequence@
23+
// CHECK: Requirement signature: <Self where Self : Sequence, Self.[Sequence]Element == Int>
24+
protocol IntSequence : Sequence<Int> {}
25+
26+
27+
/// Concrete types cannot inherit from a parametrized protocol
28+
29+
struct SillyStruct : Sequence<Int> {}
30+
// expected-error@-1 {{cannot inherit from parametrized protocol type 'Sequence<Int>'}}
31+
// expected-error@-2 {{type 'SillyStruct' does not conform to protocol 'Sequence'}}
32+
33+
34+
/// Parametrized protocol in generic parameter inheritance clause
35+
36+
// CHECK-LABEL: parametrized_protocol.(file).IntSequenceWrapper@
37+
// CHECK: Generic signature: <S where S : Sequence, S.[Sequence]Element == Int>
38+
struct IntSequenceWrapper<S : Sequence<Int>> {}
39+
40+
// CHECK-LABEL: parametrized_protocol.(file).SequenceWrapper@
41+
// CHECK: Generic signature: <S, E where S : Sequence, E == S.[Sequence]Element>
42+
struct SequenceWrapper<S : Sequence<E>, E> {}
43+
44+
45+
/// Parametrized protocol in associated type inheritance clause
46+
47+
// CHECK-LABEL: parametrized_protocol.(file).IntSequenceWrapperProtocol@
48+
// CHECK: Requirement signature: <Self where Self.[IntSequenceWrapperProtocol]S : Sequence, Self.[IntSequenceWrapperProtocol]S.[Sequence]Element == Int>
49+
protocol IntSequenceWrapperProtocol {
50+
associatedtype S : Sequence<Int>
51+
}
52+
53+
// CHECK-LABEL: parametrized_protocol.(file).SequenceWrapperProtocol@
54+
// CHECK: Requirement signature: <Self where Self.[SequenceWrapperProtocol]E == Self.[SequenceWrapperProtocol]S.[Sequence]Element, Self.[SequenceWrapperProtocol]S : Sequence>
55+
protocol SequenceWrapperProtocol {
56+
associatedtype S : Sequence<E>
57+
associatedtype E
58+
}
59+
60+
61+
/// Parametrized protocol in where clause of concrete type
62+
63+
// CHECK-LABEL: parametrized_protocol.(file).IntSequenceWrapper2@
64+
// CHECK: Generic signature: <S where S : Sequence, S.[Sequence]Element == Int>
65+
struct IntSequenceWrapper2<S> where S : Sequence<Int> {}
66+
67+
// CHECK-LABEL: parametrized_protocol.(file).SequenceWrapper2@
68+
// CHECK: Generic signature: <S, E where S : Sequence, E == S.[Sequence]Element>
69+
struct SequenceWrapper2<S, E> where S : Sequence<E> {}
70+
71+
72+
/// Parametrized protocol in where clause of associated type
73+
74+
// CHECK-LABEL: parametrized_protocol.(file).IntSequenceWrapperProtocol2@
75+
// CHECK: Requirement signature: <Self where Self.[IntSequenceWrapperProtocol2]S : Sequence, Self.[IntSequenceWrapperProtocol2]S.[Sequence]Element == Int>
76+
protocol IntSequenceWrapperProtocol2 {
77+
associatedtype S where S : Sequence<Int>
78+
}
79+
80+
// CHECK-LABEL: parametrized_protocol.(file).SequenceWrapperProtocol2@
81+
// CHECK: Requirement signature: <Self where Self.[SequenceWrapperProtocol2]E == Self.[SequenceWrapperProtocol2]S.[Sequence]Element, Self.[SequenceWrapperProtocol2]S : Sequence>
82+
protocol SequenceWrapperProtocol2 {
83+
associatedtype S where S : Sequence<E>
84+
associatedtype E
85+
}
86+
87+
88+
/// Parametrized protocol in opaque result type
89+
90+
struct OpaqueTypes<E> {
91+
func returnSequenceOfInt() -> some Sequence<Int> {
92+
return ConcreteSequence<Int>()
93+
}
94+
95+
func returnSequenceOfE() -> some Sequence<E> {
96+
return ConcreteSequence<E>()
97+
}
98+
99+
// Invalid
100+
func returnSequenceOfIntBad() -> some Sequence<Int> {
101+
// expected-note@-1 {{opaque return type declared here}}
102+
return ConcreteSequence<E>()
103+
// expected-error@-1 {{return type of instance method 'returnSequenceOfIntBad()' requires that 'E' conform to 'Int'}}
104+
}
105+
106+
// Invalid
107+
func returnEquatableSequenceBad() -> some Sequence<E> {
108+
return ConcreteEquatableSequence<E>()
109+
// expected-error@-1 {{type 'E' does not conform to protocol 'Equatable'}}
110+
}
111+
}
112+
113+
114+
/// Extensions of parametrized protocol type
115+
116+
// CHECK-LABEL: ExtensionDecl line={{[0-9]+}} base=Sequence<Int>
117+
// CHECK: Generic signature: <Self where Self : Sequence, Self.[Sequence]Element == Int>
118+
extension Sequence<Int> {
119+
120+
// CHECK-LABEL: parametrized_protocol.(file).Sequence extension.doSomethingGeneric@
121+
// CHECK: Generic signature: <Self, E where Self : Sequence, Self.[Sequence]Element == Int>
122+
func doSomethingGeneric<E>(_: E) {}
123+
}
124+
125+
126+
/// Cannot use parametrized protocol as the type of a value
127+
128+
func takesSequenceOfInt1(_: Sequence<Int>) {}
129+
// expected-error@-1 {{protocol type with generic argument can only be used as a generic constraint}}
130+
131+
func returnsSequenceOfInt1() -> Sequence<Int> {}
132+
// expected-error@-1 {{protocol type with generic argument can only be used as a generic constraint}}
133+
134+
func takesSequenceOfInt2(_: any Sequence<Int>) {}
135+
// expected-error@-1 {{protocol type with generic argument can only be used as a generic constraint}}
136+
137+
func returnsSequenceOfInt2() -> any Sequence<Int> {}
138+
// expected-error@-1 {{protocol type with generic argument can only be used as a generic constraint}}
139+
140+
func typeExpr() {
141+
_ = Sequence<Int>.self
142+
// expected-error@-1 {{protocol type with generic argument can only be used as a generic constraint}}
143+
}
144+
145+
/// Not supported as a protocol composition term for now
146+
147+
protocol SomeProto {}
148+
149+
func protocolCompositionNotSupported(_: SomeProto & Sequence<Int>) {}
150+
// expected-error@-1 {{non-protocol, non-class type 'Sequence<Int>' cannot be used within a protocol-constrained type}}
151+
// expected-warning@-2 {{protocol 'Sequence' as a type must be explicitly marked as 'any'}}
152+
153+
// FIXME: The second diagnostic is bogus.

0 commit comments

Comments
 (0)