forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththrowing_functions.swift
140 lines (108 loc) · 5.61 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
// 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 '(_) throws -> _' 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> { }
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 '(((String) -> Int)) -> Int' to expected argument type '(((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 } // 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 -> _' 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}}