forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththrowing_functions.swift
153 lines (116 loc) · 6 KB
/
throwing_functions.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
// RUN: %target-parse-verify-swift
enum Exception : ErrorType { 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 ////////////////////////////////////////////////////////
func partialApply1(a: Int)(b: Int)(c: Int) throws { } // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}}
func partialApply2<T>(a: T)(b: Int)(c: Int) throws { } // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}}
protocol Parallelogram {
static func partialApply3(a: Int) throws
}
let f11 = partialApply1
let f12 = partialApply1(1)
let f13 = partialApply1(1)(b: 2)
let f22 = partialApply2(1)
let f23 = partialApply2(1)(b: 2)
func partialApply4<T: Parallelogram>(t: T) {
_ = T.partialApply3
}
// 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 '(_) throws -> _' to non-throwing function type '(i: 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) {}
func jerry(i: Int)(j: Int) throws -> Int { return 0 } // (Int) -> (Int) throws -> Int expected-warning{{curried function declaration syntax will be removed in a future version of Swift}}
// Throwing and non-throwing types are not equivalent.
struct X<T> { }
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{{cannot convert value of type 'X<String throws -> Int>' to expected argument type 'X<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{{cannot convert value of type 'String -> (Int throws -> String)' to expected argument type 'String -> (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{{cannot convert value of type '(fn: (String -> Int)) -> Int' to expected argument type '(fn: (String throws -> Int)) -> 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 -> _' to non-throwing function type '() -> Int'}}
var c8 : () -> Int = { do { try c2() } catch _ { var x = 0 } ; return 0 }
var c9 : () -> Int = { do { try c2() } catch Exception.A { var x = 0 } ; return 0 }// expected-error{{invalid conversion from throwing function of type '() throws -> _' to non-throwing function type '() -> Int'}}
var c10 : () -> Int = { throw Exception.A; return 0 } // expected-error{{invalid conversion from throwing function of type '() throws -> _' 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}}
}
struct B {
init() throws {}
init(foo: Int) {}
}
B(foo: 0) // expected-warning{{unused}}