/
call_method_simple.swift
197 lines (176 loc) · 4.74 KB
/
call_method_simple.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
// RUN: %target-typecheck-verify-swift
struct SimpleCallable {
func callFunction(_ x: Float) -> Float {
return x
}
}
// Simple tests.
let foo = SimpleCallable()
_ = foo(1)
_ = foo(foo(1))
// TODO: Improve this error to match the error using a direct `call` member reference.
// expected-error @+2 {{cannot call value of non-function type 'SimpleCallable'}}
// expected-error @+1 {{cannot invoke 'foo' with an argument list of type '(Int, Int)'}}
_ = foo(1, 1)
// expected-error @+1 {{cannot convert value of type 'SimpleCallable' to specified type '(Float) -> Float'}}
let _: (Float) -> Float = foo
// Test direct `call` member references.
_ = foo.callFunction(1)
_ = [1, 2, 3].map(foo.callFunction)
_ = foo.callFunction(foo(1))
_ = foo(foo.callFunction(1))
let _: (Float) -> Float = foo.callFunction
func callable() -> SimpleCallable {
return SimpleCallable()
}
extension SimpleCallable {
var foo: SimpleCallable {
return self
}
func bar() -> SimpleCallable {
return self
}
}
_ = foo.foo(1)
_ = foo.bar()(1)
_ = callable()(1)
_ = [1, 2, 3].map(foo.foo.callFunction)
_ = [1, 2, 3].map(foo.bar().callFunction)
_ = [1, 2, 3].map(callable().callFunction)
struct MultipleArgsCallable {
func callFunction(x: Int, y: Float) -> [Int] {
return [x]
}
}
let bar = MultipleArgsCallable()
_ = bar(x: 1, y: 1)
_ = bar.callFunction(x: 1, y: 1)
_ = bar(x: bar.callFunction(x: 1, y: 1)[0], y: 1)
_ = bar.callFunction(x: bar(x: 1, y: 1)[0], y: 1)
_ = bar(1, 1) // expected-error {{missing argument labels 'x:y:' in call}}
struct Extended {}
extension Extended {
@discardableResult
func callFunction() -> Extended {
return self
}
}
var extended = Extended()
extended()().callFunction()()
struct TakesTrailingClosure {
func callFunction(_ fn: () -> Void) {
fn()
}
func callFunction(_ x: Int, label y: Float, _ fn: (Int, Float) -> Void) {
fn(x, y)
}
}
var takesTrailingClosure = TakesTrailingClosure()
takesTrailingClosure { print("Hi") }
takesTrailingClosure() { print("Hi") }
takesTrailingClosure(1, label: 2) { _ = Float($0) + $1 }
struct OptionalCallable {
func callFunction() -> OptionalCallable? {
return self
}
}
var optional = OptionalCallable()
_ = optional()?.callFunction()?()
struct Variadic {
func callFunction(_ args: Int...) -> [Int] {
return args
}
}
var variadic = Variadic()
_ = variadic()
_ = variadic(1, 2, 3)
struct Mutating {
var x: Int
mutating func callFunction() {
x += 1
}
}
func testMutating(_ x: Mutating, _ y: inout Mutating) {
_ = x() // expected-error {{cannot use mutating member on immutable value: 'x' is a 'let' constant}}
_ = x.callFunction() // expected-error {{cannot use mutating member on immutable value: 'x' is a 'let' constant}}
_ = y()
_ = y.callFunction()
}
struct Inout {
func callFunction(_ x: inout Int) {
x += 5
}
}
func testInout(_ x: Inout, _ arg: inout Int) {
x(&arg)
x.callFunction(&arg)
// TODO: Improve this error to match the error using a direct `call` member reference.
// expected-error @+2 {{cannot invoke 'x' with an argument list of type '(Int)'}}
// expected-error @+1 {{cannot call value of non-function type 'Inout'}}
x(arg)
// expected-error @+1 {{passing value of type 'Int' to an inout parameter requires explicit '&'}}
x.callFunction(arg)
}
struct Autoclosure {
func callFunction(_ condition: @autoclosure () -> Bool,
_ message: @autoclosure () -> String) {
if condition() {
print(message())
}
}
}
func testAutoclosure(_ x: Autoclosure) {
x(true, "Failure")
x({ true }(), { "Failure" }())
}
struct Throwing {
func callFunction() throws -> Throwing {
return self
}
func callFunction(_ f: () throws -> ()) rethrows {
try f()
}
}
struct DummyError : Error {}
var throwing = Throwing()
_ = try throwing()
_ = try throwing { throw DummyError() }
enum BinaryOperation {
case add, subtract, multiply, divide
}
extension BinaryOperation {
func callFunction(_ lhs: Float, _ rhs: Float) -> Float {
switch self {
case .add: return lhs + rhs
case .subtract: return lhs - rhs
case .multiply: return lhs * rhs
case .divide: return lhs / rhs
}
}
}
_ = BinaryOperation.add(1, 2)
class BaseClass {
func callFunction() -> Self {
return self
}
}
class SubClass : BaseClass {
override func callFunction() -> Self {
return self
}
}
func testIUO(a: SimpleCallable!, b: MultipleArgsCallable!, c: Extended!,
d: OptionalCallable!, e: Variadic!, f: inout Mutating!,
g: Inout!, inoutInt: inout Int, h: Throwing!) {
_ = a(1)
_ = b(x: 1, y: 1)
_ = c()
_ = d()?.callFunction()?()
_ = e()
_ = e(1, 2, 3)
// FIXME(TF-444): `mutating func callFunction` and IUO doesn't work.
// _ = f()
_ = g(&inoutInt)
_ = try? h()
_ = try? h { throw DummyError() }
}