-
Notifications
You must be signed in to change notification settings - Fork 10.4k
/
Copy pathcall_as_function_simple.swift
250 lines (217 loc) · 5.81 KB
/
call_as_function_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
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
// RUN: %target-typecheck-verify-swift
struct SimpleCallable {
func callAsFunction(_ x: Float) -> Float {
return x
}
}
// Simple tests.
let foo = SimpleCallable()
_ = foo(1)
_ = foo(foo(1))
_ = foo(1, 1) // expected-error@:12 {{extra argument in call}}
// expected-error @+1 {{cannot convert value of type 'SimpleCallable' to specified type '(Float) -> Float'}}
let _: (Float) -> Float = foo
// Test direct `callAsFunction` member references.
_ = foo.callAsFunction(1)
_ = [1, 2, 3].map(foo.callAsFunction)
_ = foo.callAsFunction(foo(1))
_ = foo(foo.callAsFunction(1))
let _: (Float) -> Float = foo.callAsFunction
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.callAsFunction)
_ = [1, 2, 3].map(foo.bar().callAsFunction)
_ = [1, 2, 3].map(callable().callAsFunction)
struct MultipleArgsCallable {
func callAsFunction(x: Int, y: Float) -> [Int] {
return [x]
}
}
let bar = MultipleArgsCallable()
_ = bar(x: 1, y: 1)
_ = bar.callAsFunction(x: 1, y: 1)
_ = bar(x: bar.callAsFunction(x: 1, y: 1)[0], y: 1)
_ = bar.callAsFunction(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 callAsFunction() -> Extended {
return self
}
func callAsFunction(_: Int) -> Extended {
return self
}
}
var extended = Extended()
extended()().callAsFunction()()
// Test diagnostic location
extended()().callAsFunction()(1) // expected-warning@:30 {{result of call to 'callAsFunction' is unused}}
extended()().callAsFunction(1) // expected-warning@:14 {{result of call to 'callAsFunction' is unused}}
struct TakesTrailingClosure {
func callAsFunction(_ fn: () -> Void) {
fn()
}
func callAsFunction(_ 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 callAsFunction() -> OptionalCallable? {
return self
}
}
var optional = OptionalCallable()
_ = optional()?.callAsFunction()?()
struct Variadic {
func callAsFunction(_ args: Int...) -> [Int] {
return args
}
}
var variadic = Variadic()
_ = variadic()
_ = variadic(1, 2, 3)
struct Mutating {
var x: Int
mutating func callAsFunction() {
x += 1
}
}
func testMutating(_ x: Mutating, _ y: inout Mutating) {
// expected-error @+1 {{cannot use mutating member on immutable value: 'x' is a 'let' constant}}
_ = x()
// expected-error @+1 {{cannot use mutating member on immutable value: 'x' is a 'let' constant}}
_ = x.callAsFunction()
y()
y.callAsFunction()
}
struct Inout {
func callAsFunction(_ x: inout Int) {
x += 5
}
}
func testInout(_ x: Inout, _ arg: inout Int) {
x(&arg)
x.callAsFunction(&arg)
// expected-error @+1 {{passing value of type 'Int' to an inout parameter requires explicit '&'}}
x(arg)
// expected-error @+1 {{passing value of type 'Int' to an inout parameter requires explicit '&'}}
x.callAsFunction(arg)
}
struct Autoclosure {
func callAsFunction(_ condition: @autoclosure () -> Bool,
_ message: @autoclosure () -> String) {
if condition() {
print(message())
}
}
}
func testAutoclosure(_ x: Autoclosure) {
x(true, "Failure")
x({ true }(), { "Failure" }())
}
struct Throwing {
func callAsFunction() throws -> Throwing {
return self
}
func callAsFunction(_ 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 callAsFunction(_ 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 callAsFunction() -> Self {
return self
}
}
class SubClass : BaseClass {
override func callAsFunction() -> 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()?.callAsFunction()?()
_ = e()
_ = e(1, 2, 3)
f()
g(&inoutInt)
_ = try? h()
_ = try? h { throw DummyError() }
}
// https://github.com/apple/swift/issues/54185
struct DoubleANumber {
func callAsFunction(_ x: Int, completion: (Int) -> Void = { _ in }) {
completion(x + x)
}
}
func testDefaults(_ x: DoubleANumber) {
x(5)
x(5, completion: { _ in })
}
// https://github.com/apple/swift/issues/54296
struct IUOCallable {
static var callable: IUOCallable { IUOCallable() }
func callAsFunction(_ x: Int) -> IUOCallable! { nil }
}
func testIUOCallAsFunction(_ x: IUOCallable) {
let _: IUOCallable = x(5)
let _: IUOCallable? = x(5)
let _ = x(5)
let _: IUOCallable = .callable(5)
let _: IUOCallable? = .callable(5)
}
// Test access control.
struct PrivateCallable {
private func callAsFunction(_ x: Int) {} // expected-note {{'callAsFunction' declared here}}
}
func testAccessControl(_ x: PrivateCallable) {
x(5) // expected-error {{'callAsFunction' is inaccessible due to 'private' protection level}}
}
// https://github.com/apple/swift/issues/54327
do {
struct S {
static let s = S()
func callAsFunction(_ x: Int = 0) -> S {}
}
// Test default argument with 'UnresolvedMemberExpr'.
let _: S = .s()
let _: S = .s(5)
}