forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathswitch.swift
312 lines (260 loc) · 10.4 KB
/
switch.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
// RUN: %target-typecheck-verify-swift
// TODO: Implement tuple equality in the library.
// BLOCKED: <rdar://problem/13822406>
func ~= (x: (Int,Int), y: (Int,Int)) -> Bool {
return true
}
func parseError1(x: Int) {
switch func {} // expected-error {{expected expression in 'switch' statement}} expected-error {{expected '{' after 'switch' subject expression}} expected-error {{expected identifier in function declaration}} expected-error {{closure expression is unused}} expected-note{{did you mean to use a 'do' statement?}} {{15-15=do }}
}
func parseError2(x: Int) {
switch x // expected-error {{expected '{' after 'switch' subject expression}}
}
func parseError3(x: Int) {
switch x {
case // expected-error {{expected pattern}} expected-error {{expected ':' after 'case'}}
}
}
func parseError4(x: Int) {
switch x {
case var z where // expected-error {{expected expression for 'where' guard of 'case'}} expected-error {{expected ':' after 'case'}}
}
}
func parseError5(x: Int) {
switch x {
case let z // expected-error {{expected ':' after 'case'}} expected-warning {{immutable value 'z' was never used}} {{12-13=_}}
}
}
func parseError6(x: Int) {
switch x {
default // expected-error {{expected ':' after 'default'}}
}
}
var x: Int
switch x {} // expected-error {{'switch' statement body must have at least one 'case' or 'default' block}}
switch x {
case 0:
x = 0
// Multiple patterns per case
case 1, 2, 3:
x = 0
// 'where' guard
case _ where x % 2 == 0:
x = 1
x = 2
x = 3
case _ where x % 2 == 0,
_ where x % 3 == 0:
x = 1
case 10,
_ where x % 3 == 0:
x = 1
case _ where x % 2 == 0,
20:
x = 1
case var y where y % 2 == 0:
x = y + 1
case _ where 0: // expected-error {{'Int' is not convertible to 'Bool'}}
x = 0
default:
x = 1
}
// Multiple cases per case block
switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
case 0: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}}
case 1:
x = 0
}
switch x {
case 0: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}}
default:
x = 0
}
switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
case 0:
x = 0
case 1: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}}
}
switch x {
case 0:
x = 0
default: // expected-error {{'default' label in a 'switch' should have at least one executable statement}} {{9-9= break}}
}
switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
case 0:
; // expected-error {{';' statements are not allowed}} {{3-5=}}
case 1:
x = 0
}
switch x {
x = 1 // expected-error{{all statements inside a switch must be covered by a 'case' or 'default'}}
default:
x = 0
case 0: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}}
x = 0
case 1:
x = 0
}
switch x {
default:
x = 0
default: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}}
x = 0
}
switch x { // expected-error{{'switch' statement body must have at least one 'case' or 'default' block}}
x = 1 // expected-error{{all statements inside a switch must be covered by a 'case' or 'default'}}
}
switch x { // expected-error{{'switch' statement body must have at least one 'case' or 'default' block}}
x = 1 // expected-error{{all statements inside a switch must be covered by a 'case' or 'default'}}
x = 2
}
switch x {
default: // expected-error{{'default' label in a 'switch' should have at least one executable statement}} {{9-9= break}}
case 0: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}}
x = 0
}
switch x {
default: // expected-error{{'default' label in a 'switch' should have at least one executable statement}} {{9-9= break}}
default: // expected-error{{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}}
x = 0
}
switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
default where x == 0: // expected-error{{'default' cannot be used with a 'where' guard expression}}
x = 0
}
switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
case 0: // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}}
}
switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
case 0: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}}
case 1:
x = 0
}
switch x { // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
case 0:
x = 0
case 1: // expected-error{{'case' label in a 'switch' should have at least one executable statement}} {{8-8= break}}
}
case 0: // expected-error{{'case' label can only appear inside a 'switch' statement}}
var y = 0
default: // expected-error{{'default' label can only appear inside a 'switch' statement}}
var z = 1
fallthrough // expected-error{{'fallthrough' is only allowed inside a switch}}
switch x {
case 0:
fallthrough
case 1:
fallthrough
default:
fallthrough // expected-error{{'fallthrough' without a following 'case' or 'default' block}}
}
// Fallthrough can transfer control anywhere within a case and can appear
// multiple times in the same case.
switch x {
case 0:
if true { fallthrough }
if false { fallthrough }
x += 1
default:
x += 1
}
// Cases cannot contain 'var' bindings if there are multiple matching patterns
// attached to a block. They may however contain other non-binding patterns.
var t = (1, 2)
switch t {
case (var a, 2), (1, _): // expected-error {{'a' must be bound in every pattern}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}}
()
case (_, 2), (var a, _): // expected-error {{'a' must be bound in every pattern}}
()
case (var a, 2), (1, var b): // expected-error {{'a' must be bound in every pattern}} expected-error {{'b' must be bound in every pattern}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}}
()
case (var a, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{17-17= break}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}}
case (1, _):
()
case (_, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{13-13= break}}
case (1, var a): // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}}
()
case (var a, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{17-17= break}} expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}}
case (1, var b): // expected-warning {{variable 'b' was never used; consider replacing with '_' or removing it}}
()
case (1, let b): // let bindings expected-warning {{immutable value 'b' was never used; consider replacing with '_' or removing it}}
()
case (_, 2), (let a, _): // expected-error {{'a' must be bound in every pattern}} expected-warning {{case is already handled by previous patterns; consider removing it}}
()
// OK
case (_, 2), (1, _):
()
case (_, var a), (_, var a): // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}}
// expected-warning@-1 {{case is already handled by previous patterns; consider removing it}}
// expected-warning@-2 {{case is already handled by previous patterns; consider removing it}}
()
case (var a, var b), (var b, var a): // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} expected-warning {{variable 'b' was never used; consider replacing with '_' or removing it}}
// expected-warning@-1 {{case is already handled by previous patterns; consider removing it}}
// expected-warning@-2 {{case is already handled by previous patterns; consider removing it}}
()
case (_, 2): // expected-error {{'case' label in a 'switch' should have at least one executable statement}} {{13-13= break}}
case (1, _):
()
}
func patternVarUsedInAnotherPattern(x: Int) {
switch x {
case let a, // expected-error {{'a' must be bound in every pattern}}
a:
break
}
}
// Fallthroughs can't transfer control into a case label with bindings.
switch t {
case (1, 2):
fallthrough // expected-error {{'fallthrough' cannot transfer control to a case label that declares variables}}
case (var a, var b): // expected-warning {{variable 'a' was never mutated; consider changing to 'let' constant}} expected-warning {{variable 'b' was never mutated; consider changing to 'let' constant}}
t = (b, a)
}
func test_label(x : Int) {
Gronk: // expected-error {{switch must be exhaustive}} expected-note{{do you want to add a default clause?}}
switch x {
case 42: return
}
}
func enumElementSyntaxOnTuple() {
switch (1, 1) {
case .Bar: // expected-error {{pattern cannot match values of type '(Int, Int)'}}
break
default:
break
}
}
// sr-176
enum Whatever { case Thing }
func f0(values: [Whatever]) { // expected-note {{did you mean 'values'?}}
switch value { // expected-error {{use of unresolved identifier 'value'}}
case .Thing: // Ok. Don't emit diagnostics about enum case not found in type <<error type>>.
break
}
}
// sr-720
enum Whichever {
case Thing
static let title = "title"
static let alias: Whichever = .Thing
}
func f1(x: String, y: Whichever) {
switch x {
case Whichever.title: // Ok. Don't emit diagnostics for static member of enum.
break
case Whichever.buzz: // expected-error {{type 'Whichever' has no member 'buzz'}}
break
case Whichever.alias: // expected-error {{expression pattern of type 'Whichever' cannot match values of type 'String'}}
break
default:
break
}
switch y {
case Whichever.Thing: // Ok.
break
case Whichever.alias: // Ok. Don't emit diagnostics for static member of enum.
break
case Whichever.title: // expected-error {{expression pattern of type 'String' cannot match values of type 'Whichever'}}
break
}
}