File: throwing_functions.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (293 lines) | stat: -rw-r--r-- 11,233 bytes parent folder | download
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
// RUN: %target-typecheck-verify-swift

enum Exception : Error { case A }

// Basic syntax ///////////////////////////////////////////////////////////////
func bar() throws -> Int { return 0 }
func foo() -> Int { return 0 }


// Currying ///////////////////////////////////////////////////////////////////
func curry1() {

}

func curry1Throws() throws {

}

func curry2() -> () -> () {
	return curry1
}

func curry2Throws() throws -> () -> () {
	return curry1
}

func curry3() -> () throws -> () {
	return curry1Throws
}

func curry3Throws() throws -> () throws -> () {
	return curry1Throws
}

var a : () -> () -> () = curry2
var b : () throws -> () -> () = curry2Throws
var c : () -> () throws -> () = curry3
var d : () throws -> () throws -> () = curry3Throws

// Partial application ////////////////////////////////////////////////////////

protocol Parallelogram {
  static func partialApply1(_ a: Int) throws
}

func partialApply2<T: Parallelogram>(_ t: T) {
  _ = T.partialApply1
}

// Overload resolution/////////////////////////////////////////////////////////
func barG<T>(_ t : T) throws -> T { return t }
func fooG<T>(_ t : T) -> T { return t }

var bGE: (_ i: Int) -> Int = barG // expected-error{{invalid conversion from throwing function of type '(Int) throws -> Int' to non-throwing function type '(Int) -> Int'}}
var bg: (_ i: Int) throws -> Int = barG
var fG: (_ i: Int) throws -> Int = fooG

func fred(_ callback: (UInt8) throws -> ()) throws { }

func rachel() -> Int { return 12 }
func donna(_ generator: () throws -> Int) -> Int { return generator() } // expected-error {{call can throw, but it is not marked with 'try' and the error is not handled}}

_ = donna(rachel)

func barT() throws -> Int { return 0 } // expected-note{{}}
func barT() -> Int { return 0 } // expected-error{{invalid redeclaration of 'barT()'}}

func fooT(_ callback: () throws -> Bool) {} //OK
func fooT(_ callback: () -> Bool) {}

// Throwing and non-throwing types are not equivalent.
struct X<T> { }
// expected-note@-1{{arguments to generic parameter 'T' ('(String) -> Int' and '(String) throws -> Int') are expected to be equal}}

func specializedOnFuncType1(_ x: X<(String) throws -> Int>) { }
func specializedOnFuncType2(_ x: X<(String) -> Int>) { }
func testSpecializedOnFuncType(_ xThrows: X<(String) throws -> Int>,
                               xNonThrows: X<(String) -> Int>) {
  specializedOnFuncType1(xThrows) // ok
  specializedOnFuncType1(xNonThrows) // expected-error{{cannot convert value of type 'X<(String) -> Int>' to expected argument type 'X<(String) throws -> Int>'}}
  specializedOnFuncType2(xThrows)  // expected-error{{invalid conversion from throwing function of type '(String) throws -> Int' to non-throwing function type '(String) -> Int'}}
  specializedOnFuncType2(xNonThrows) // ok
}

// Subtyping
func subtypeResult1(_ x: (String) -> ((Int) -> String)) { }
func testSubtypeResult1(_ x1: (String) -> ((Int) throws -> String),
                        x2: (String) -> ((Int) -> String)) {
  subtypeResult1(x1) // expected-error{{invalid conversion from throwing function of type '(Int) throws -> String' to non-throwing function type '(Int) -> String'}}
  subtypeResult1(x2)
}

func subtypeResult2(_ x: (String) -> ((Int) throws -> String)) { }
func testSubtypeResult2(_ x1: (String) -> ((Int) throws -> String),
                        x2: (String) -> ((Int) -> String)) {
  subtypeResult2(x1)
  subtypeResult2(x2)
}

func subtypeArgument1(_ x: (_ fn: ((String) -> Int)) -> Int) { }
func testSubtypeArgument1(_ x1: (_ fn: ((String) -> Int)) -> Int,
                          x2: (_ fn: ((String) throws -> Int)) -> Int) {
  subtypeArgument1(x1)
  subtypeArgument1(x2)
}

func subtypeArgument2(_ x: (_ fn: ((String) throws -> Int)) -> Int) { }
func testSubtypeArgument2(_ x1: (_ fn: ((String) -> Int)) -> Int,
                          x2: (_ fn: ((String) throws -> Int)) -> Int) {
  subtypeArgument2(x1) // expected-error{{invalid conversion from throwing function of type '(String) throws -> Int' to non-throwing function type '(String) -> Int'}}
  subtypeArgument2(x2)
}

// Closures
var c1 = {() throws -> Int in 0}
var c2 : () throws -> Int = c1 // ok
var c3 : () -> Int = c1 // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c4 : () -> Int = {() throws -> Int in 0} // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c5 : () -> Int = { try c2() } // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c6 : () throws -> Int = { do { _ = try c2() } ; return 0 }
var c7 : () -> Int = { do { try c2() } ; return 0 } // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c8 : () -> Int = { do { _ = try c2()  } catch _ { var x = 0 } ; return 0 } // expected-warning {{initialization of variable 'x' was never used; consider replacing with assignment to '_' or removing it}}
var c9 : () -> Int = { do { try c2()  } catch Exception.A { var x = 0 } ; return 0 }// expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c10 : () -> Int = { throw Exception.A; return 0 } // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c11 : () -> Int = { try! c2() }
var c12 : () -> Int? = { try? c2() }

// Initializers
struct A {
    init(doomed: ()) throws {}
}

func fi1() throws {
    A(doomed: ()) // expected-error {{call can throw but is not marked with 'try'}} // expected-warning{{unused}}
    // expected-note@-1 {{did you mean to use 'try'?}} {{5-5=try }}
    // expected-note@-2 {{did you mean to handle error as optional value?}} {{5-5=try? }}
    // expected-note@-3 {{did you mean to disable error propagation?}} {{5-5=try! }}
}

struct B {
 init() throws {}
 init(foo: Int) {}
}

B(foo: 0) // expected-warning{{unused}}

// rdar://problem/33040113 - Provide fix-it for missing "try" when calling throwing Swift function

class E_33040113 : Error {}
func rdar33040113() throws -> Int {
    throw E_33040113()
}

let _ = rdar33040113() // expected-error {{call can throw but is not marked with 'try'}}
// expected-note@-1 {{did you mean to use 'try'?}} {{9-9=try }}
// expected-note@-2 {{did you mean to handle error as optional value?}} {{9-9=try? }}
// expected-note@-3 {{did you mean to disable error propagation?}} {{9-9=try! }}

enum MSV : Error {
  case Foo, Bar, Baz
  case CarriesInt(Int)
}

func genError() throws -> Int { throw MSV.Foo }

struct IllegalContext {
  var x1: Int = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  let x2 = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  var x3 = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  let x4: Int = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  var x5 = B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  var x6 = try B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  var x7 = { // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
    return try genError()
  }()

  var x8: Int = {
    do {
      return genError() // expected-error {{call can throw but is not marked with 'try'}}
      // expected-note@-1 {{did you mean to use 'try'?}}
      // expected-note@-2 {{did you mean to handle error as optional value?}}
      // expected-note@-3 {{did you mean to disable error propagation?}}
    } catch {
      return 0
    }
  }()

  var x9: Int = {
    do {
      return try genError()
    } catch {
      return 0
    }
  }()

  var x10: B = {
    do {
      return try B()
    } catch {
      return B(foo: 0)
    }
  }()

  lazy var y1: Int = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  lazy var y2 = genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  lazy var y3 = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  lazy var y4: Int = try genError() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  lazy var y5 = B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  lazy var y6 = try B() // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}

  lazy var y7 = { // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
    return try genError()
  }()

  lazy var y8: Int = {
    do {
      return genError() // expected-error {{call can throw but is not marked with 'try'}}
      // expected-note@-1 {{did you mean to use 'try'?}}
      // expected-note@-2 {{did you mean to handle error as optional value?}}
      // expected-note@-3 {{did you mean to disable error propagation?}}
    } catch {
      return 0
    }
  }()

  lazy var y9: Int = {
    do {
      return try genError()
    } catch {
      return 0
    }
  }()

  lazy var y10: B = {
    do {
      return try B()
    } catch {
      return B(foo: 0)
    }
  }()

  func foo(_ x: Int = genError()) {} // expected-error {{call can throw, but errors cannot be thrown out of a default argument}}

  func catcher() throws {
    do {
      _ = try genError()
    } catch MSV.CarriesInt(genError()) { // expected-error {{call can throw, but errors cannot be thrown out of a catch pattern}}
    } catch MSV.CarriesInt(let i) where i == genError() { // expected-error {{call can throw, but errors cannot be thrown out of a catch guard expression}}
    }
  }
}

// Crash in 'uncovered try' diagnostic when calling a function value - rdar://46973064
struct FunctionHolder {
  let fn: () throws -> ()
  func receive() {
    do {
      _ = fn()
      // expected-error@-1 {{call can throw but is not marked with 'try'}}
      // expected-note@-2 {{did you mean to use 'try'?}}
      // expected-note@-3 {{did you mean to handle error as optional value?}}
      // expected-note@-4 {{did you mean to disable error propagation?}}
      _ = "\(fn())"
      // expected-error@-1 {{call can throw but is not marked with 'try'}}
      // expected-note@-2 {{did you mean to use 'try'?}}
      // expected-note@-3 {{did you mean to handle error as optional value?}}
      // expected-note@-4 {{did you mean to disable error propagation?}}
    } catch {}
  }
}

// https://github.com/apple/swift/issues/61368

@propertyWrapper
struct Wrapper {
  var wrappedValue: Int?
  init() throws {}
}

struct Repro {
  @Wrapper var x // expected-error {{call can throw, but errors cannot be thrown out of a property initializer}}
}