|
1 | 1 | // RUN: %target-typecheck-verify-swift
|
2 | 2 |
|
| 3 | +var func6 : (_ fn : (Int,Int) -> Int) -> () |
| 4 | +var func6a : ((Int, Int) -> Int) -> () |
| 5 | +var func6b : (Int, (Int, Int) -> Int) -> () |
| 6 | +func func6c(_ f: (Int, Int) -> Int, _ n: Int = 0) {} |
| 7 | + |
| 8 | + |
| 9 | +// Expressions can be auto-closurified, so that they can be evaluated separately |
| 10 | +// from their definition. |
| 11 | +var closure1 : () -> Int = {4} // Function producing 4 whenever it is called. |
| 12 | +var closure2 : (Int,Int) -> Int = { 4 } // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{36-36= _,_ in}} |
| 13 | +var closure3a : () -> () -> (Int,Int) = {{ (4, 2) }} // multi-level closing. |
| 14 | +var closure3b : (Int,Int) -> (Int) -> (Int,Int) = {{ (4, 2) }} // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{52-52=_,_ in }} |
| 15 | +var closure4 : (Int,Int) -> Int = { $0 + $1 } |
| 16 | +var closure5 : (Double) -> Int = { |
| 17 | + $0 + 1.0 |
| 18 | + // expected-error@-1 {{cannot convert value of type 'Double' to closure result type 'Int'}} |
| 19 | +} |
| 20 | + |
| 21 | +var closure6 = $0 // expected-error {{anonymous closure argument not contained in a closure}} |
| 22 | + |
| 23 | +var closure7 : Int = { 4 } // expected-error {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{27-27=()}} // expected-note {{Remove '=' to make 'closure7' a computed property}}{{20-22=}} |
| 24 | + |
| 25 | +var capturedVariable = 1 |
| 26 | +var closure8 = { [capturedVariable] in |
| 27 | + capturedVariable += 1 // expected-error {{left side of mutating operator isn't mutable: 'capturedVariable' is an immutable capture}} |
| 28 | +} |
| 29 | + |
| 30 | +func funcdecl1(_ a: Int, _ y: Int) {} |
| 31 | +func funcdecl3() -> Int {} |
| 32 | +func funcdecl4(_ a: ((Int) -> Int), _ b: Int) {} |
| 33 | + |
| 34 | +func funcdecl5(_ a: Int, _ y: Int) { |
| 35 | + // Pass in a closure containing the call to funcdecl3. |
| 36 | + funcdecl4({ funcdecl3() }, 12) // expected-error {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{14-14= _ in}} |
| 37 | + |
| 38 | + |
| 39 | + func6({$0 + $1}) // Closure with two named anonymous arguments |
| 40 | + func6({($0) + $1}) // Closure with sequence expr inferred type |
| 41 | + func6({($0) + $0}) // // expected-error {{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 1 was used in closure body}} |
| 42 | + |
| 43 | + |
| 44 | + var testfunc : ((), Int) -> Int // expected-note {{'testfunc' declared here}} |
| 45 | + testfunc({$0+1}) // expected-error {{missing argument for parameter #2 in call}} |
| 46 | + |
| 47 | + funcdecl5(1, 2) // recursion. |
| 48 | + |
| 49 | + // Element access from a tuple. |
| 50 | + var a : (Int, f : Int, Int) |
| 51 | + var b = a.1+a.f |
| 52 | + |
| 53 | + // Tuple expressions with named elements. |
| 54 | + var i : (y : Int, x : Int) = (x : 42, y : 11) |
| 55 | + funcdecl1(123, 444) |
| 56 | + |
| 57 | + // Calls. |
| 58 | + 4() // expected-error {{cannot call value of non-function type 'Int'}}{{4-6=}} |
| 59 | + |
| 60 | + |
| 61 | + // rdar://12017658 - Infer some argument types from func6. |
| 62 | + func6({ a, b -> Int in a+b}) |
| 63 | + // Return type inference. |
| 64 | + func6({ a,b in a+b }) |
| 65 | + |
| 66 | + // Infer incompatible type. |
| 67 | + func6({a,b -> Float in 4.0 }) // expected-error {{declared closure result 'Float' is incompatible with contextual type 'Int'}} {{17-22=Int}} // Pattern doesn't need to name arguments. |
| 68 | + func6({ _,_ in 4 }) |
| 69 | + |
| 70 | + func6({a,b in 4.0 }) // expected-error {{cannot convert value of type 'Double' to closure result type 'Int'}} |
| 71 | + |
| 72 | + // TODO: This diagnostic can be improved: rdar://22128205 |
| 73 | + func6({(a : Float, b) in 4 }) // expected-error {{cannot convert value of type '(Float, _) -> Int' to expected argument type '(Int, Int) -> Int'}} |
| 74 | + |
| 75 | + |
| 76 | + |
| 77 | + var fn = {} |
| 78 | + var fn2 = { 4 } |
| 79 | + |
| 80 | + |
| 81 | + var c : Int = { a,b -> Int in a+b} // expected-error{{cannot convert value of type '(Int, Int) -> Int' to specified type 'Int'}} |
| 82 | + |
| 83 | + |
| 84 | +} |
| 85 | + |
| 86 | +func unlabeledClosureArgument() { |
| 87 | + |
| 88 | + func add(_ x: Int, y: Int) -> Int { return x + y } |
| 89 | + func6a({$0 + $1}) // single closure argument |
| 90 | + func6a(add) |
| 91 | + func6b(1, {$0 + $1}) // second arg is closure |
| 92 | + func6b(1, add) |
| 93 | + func6c({$0 + $1}) // second arg is default int |
| 94 | + func6c(add) |
| 95 | +} |
| 96 | + |
| 97 | +// rdar://11935352 - closure with no body. |
| 98 | +func closure_no_body(_ p: () -> ()) { |
| 99 | + return closure_no_body({}) |
| 100 | +} |
| 101 | + |
| 102 | + |
| 103 | +// rdar://12019415 |
| 104 | +func t() { |
| 105 | + let u8 : UInt8 = 1 |
| 106 | + let x : Bool = true |
| 107 | + |
| 108 | + if 0xA0..<0xBF ~= Int(u8) && x { |
| 109 | + } |
| 110 | +} |
| 111 | + |
| 112 | +// <rdar://problem/11927184> |
| 113 | +func f0(_ a: Any) -> Int { return 1 } |
| 114 | +assert(f0(1) == 1) |
| 115 | + |
| 116 | + |
| 117 | +var selfRef = { selfRef() } // expected-error {{variable used within its own initial value}} |
| 118 | +var nestedSelfRef = { |
| 119 | + var recursive = { nestedSelfRef() } // expected-error {{variable used within its own initial value}} |
| 120 | + recursive() |
| 121 | +} |
| 122 | + |
| 123 | +var shadowed = { (shadowed: Int) -> Int in |
| 124 | + let x = shadowed |
| 125 | + return x |
| 126 | +} // no-warning |
| 127 | +var shadowedShort = { (shadowedShort: Int) -> Int in shadowedShort+1 } // no-warning |
| 128 | + |
| 129 | + |
| 130 | +func anonymousClosureArgsInClosureWithArgs() { |
| 131 | + func f(_: String) {} |
| 132 | + var a1 = { () in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} |
| 133 | + var a2 = { () -> Int in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} |
| 134 | + var a3 = { (z: Int) in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'z'?}} {{26-28=z}} |
| 135 | + var a4 = { (z: [Int], w: [Int]) in |
| 136 | + f($0.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'z'?}} {{7-9=z}} expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}} |
| 137 | + f($1.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'w'?}} {{7-9=w}} expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}} |
| 138 | + } |
| 139 | + var a5 = { (_: [Int], w: [Int]) in |
| 140 | + f($0.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} |
| 141 | + f($1.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean 'w'?}} {{7-9=w}} expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}} |
| 142 | + } |
| 143 | +} |
| 144 | + |
3 | 145 | func doStuff(_ fn : @escaping () -> Int) {}
|
4 | 146 | func doVoidStuff(_ fn : @escaping () -> ()) {}
|
5 | 147 |
|
@@ -63,3 +205,187 @@ class ExplicitSelfRequiredTest {
|
63 | 205 | return 42
|
64 | 206 | }
|
65 | 207 | }
|
| 208 | + |
| 209 | + |
| 210 | +class SomeClass { |
| 211 | + var field : SomeClass? |
| 212 | + func foo() -> Int {} |
| 213 | +} |
| 214 | + |
| 215 | +func testCaptureBehavior(_ ptr : SomeClass) { |
| 216 | + // Test normal captures. |
| 217 | + weak var wv : SomeClass? = ptr |
| 218 | + unowned let uv : SomeClass = ptr |
| 219 | + unowned(unsafe) let uv1 : SomeClass = ptr |
| 220 | + unowned(safe) let uv2 : SomeClass = ptr |
| 221 | + doStuff { wv!.foo() } |
| 222 | + doStuff { uv.foo() } |
| 223 | + doStuff { uv1.foo() } |
| 224 | + doStuff { uv2.foo() } |
| 225 | + |
| 226 | + |
| 227 | + // Capture list tests |
| 228 | + let v1 : SomeClass? = ptr |
| 229 | + let v2 : SomeClass = ptr |
| 230 | + |
| 231 | + doStuff { [weak v1] in v1!.foo() } |
| 232 | + // expected-warning @+2 {{variable 'v1' was written to, but never read}} |
| 233 | + doStuff { [weak v1, // expected-note {{previous}} |
| 234 | + weak v1] in v1!.foo() } // expected-error {{definition conflicts with previous value}} |
| 235 | + doStuff { [unowned v2] in v2.foo() } |
| 236 | + doStuff { [unowned(unsafe) v2] in v2.foo() } |
| 237 | + doStuff { [unowned(safe) v2] in v2.foo() } |
| 238 | + doStuff { [weak v1, weak v2] in v1!.foo() + v2!.foo() } |
| 239 | + |
| 240 | + let i = 42 |
| 241 | + // expected-warning @+1 {{variable 'i' was never mutated}} {{19-20=let}} |
| 242 | + doStuff { [weak i] in i! } // expected-error {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}} |
| 243 | +} |
| 244 | + |
| 245 | +extension SomeClass { |
| 246 | + func bar() { |
| 247 | + doStuff { [unowned self] in self.foo() } |
| 248 | + doStuff { [unowned xyz = self.field!] in xyz.foo() } |
| 249 | + doStuff { [weak xyz = self.field] in xyz!.foo() } |
| 250 | + |
| 251 | + // rdar://16889886 - Assert when trying to weak capture a property of self in a lazy closure |
| 252 | + doStuff { [weak self.field] in field!.foo() } // expected-error {{fields may only be captured by assigning to a specific name}} expected-error {{reference to property 'field' in closure requires explicit 'self.' to make capture semantics explicit}} {{36-36=self.}} |
| 253 | + // expected-warning @+1 {{variable 'self' was written to, but never read}} |
| 254 | + doStuff { [weak self&field] in 42 } // expected-error {{expected ']' at end of capture list}} |
| 255 | + |
| 256 | + } |
| 257 | + |
| 258 | + func strong_in_capture_list() { |
| 259 | + // <rdar://problem/18819742> QOI: "[strong self]" in capture list generates unhelpful error message |
| 260 | + _ = {[strong self] () -> () in return } // expected-error {{expected 'weak', 'unowned', or no specifier in capture list}} |
| 261 | + } |
| 262 | +} |
| 263 | + |
| 264 | + |
| 265 | +// <rdar://problem/16955318> Observed variable in a closure triggers an assertion |
| 266 | +var closureWithObservedProperty: () -> () = { |
| 267 | + var a: Int = 42 { |
| 268 | + willSet { |
| 269 | + _ = "Will set a to \(newValue)" |
| 270 | + } |
| 271 | + didSet { |
| 272 | + _ = "Did set a with old value of \(oldValue)" |
| 273 | + } |
| 274 | + } |
| 275 | +} |
| 276 | + |
| 277 | +; |
| 278 | + |
| 279 | +{}() // expected-error{{top-level statement cannot begin with a closure expression}} |
| 280 | + |
| 281 | + |
| 282 | + |
| 283 | +// rdar://19179412 - Crash on valid code. |
| 284 | +func rdar19179412() -> (Int) -> Int { |
| 285 | + return { x in |
| 286 | + class A { |
| 287 | + let d : Int = 0 |
| 288 | + } |
| 289 | + return 0 |
| 290 | + } |
| 291 | +} |
| 292 | + |
| 293 | +// Test coercion of single-expression closure return types to void. |
| 294 | +func takesVoidFunc(_ f: () -> ()) {} |
| 295 | +var i: Int = 1 |
| 296 | + |
| 297 | +// expected-warning @+1 {{expression of type 'Int' is unused}} |
| 298 | +takesVoidFunc({i}) |
| 299 | +// expected-warning @+1 {{expression of type 'Int' is unused}} |
| 300 | +var f1: () -> () = {i} |
| 301 | +var x = {return $0}(1) |
| 302 | + |
| 303 | +func returnsInt() -> Int { return 0 } |
| 304 | +takesVoidFunc(returnsInt) // expected-error {{cannot convert value of type '() -> Int' to expected argument type '() -> ()'}} |
| 305 | +takesVoidFunc({() -> Int in 0}) // expected-error {{declared closure result 'Int' is incompatible with contextual type '()'}} {{22-25=()}} |
| 306 | + |
| 307 | +// These used to crash the compiler, but were fixed to support the implementation of rdar://problem/17228969 |
| 308 | +Void(0) // expected-error{{argument passed to call that takes no arguments}} |
| 309 | +_ = {0} |
| 310 | + |
| 311 | +// <rdar://problem/22086634> "multi-statement closures require an explicit return type" should be an error not a note |
| 312 | +let samples = { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{16-16= () -> Bool in }} |
| 313 | + if (i > 10) { return true } |
| 314 | + else { return false } |
| 315 | + }() |
| 316 | + |
| 317 | +// <rdar://problem/19756953> Swift error: cannot capture '$0' before it is declared |
| 318 | +func f(_ fp : (Bool, Bool) -> Bool) {} |
| 319 | +f { $0 && !$1 } |
| 320 | + |
| 321 | + |
| 322 | +// <rdar://problem/18123596> unexpected error on self. capture inside class method |
| 323 | +func TakesIntReturnsVoid(_ fp : ((Int) -> ())) {} |
| 324 | + |
| 325 | +struct TestStructWithStaticMethod { |
| 326 | + static func myClassMethod(_ count: Int) { |
| 327 | + // Shouldn't require "self." |
| 328 | + TakesIntReturnsVoid { _ in myClassMethod(0) } |
| 329 | + } |
| 330 | +} |
| 331 | + |
| 332 | +class TestClassWithStaticMethod { |
| 333 | + class func myClassMethod(_ count: Int) { |
| 334 | + // Shouldn't require "self." |
| 335 | + TakesIntReturnsVoid { _ in myClassMethod(0) } |
| 336 | + } |
| 337 | +} |
| 338 | + |
| 339 | +// Test that we can infer () as the result type of these closures. |
| 340 | +func genericOne<T>(_ a: () -> T) {} |
| 341 | +func genericTwo<T>(_ a: () -> T, _ b: () -> T) {} |
| 342 | +genericOne {} |
| 343 | +genericTwo({}, {}) |
| 344 | + |
| 345 | + |
| 346 | +// <rdar://problem/22344208> QoI: Warning for unused capture list variable should be customized |
| 347 | +class r22344208 { |
| 348 | + func f() { |
| 349 | + let q = 42 |
| 350 | + let _: () -> Int = { |
| 351 | + [unowned self, // expected-warning {{capture 'self' was never used}} |
| 352 | + q] in // expected-warning {{capture 'q' was never used}} |
| 353 | + 1 } |
| 354 | + } |
| 355 | +} |
| 356 | + |
| 357 | +var f = { (s: Undeclared) -> Int in 0 } // expected-error {{use of undeclared type 'Undeclared'}} |
| 358 | + |
| 359 | +// <rdar://problem/21375863> Swift compiler crashes when using closure, declared to return illegal type. |
| 360 | +func r21375863() { |
| 361 | + var width = 0 |
| 362 | + var height = 0 |
| 363 | + var bufs: [[UInt8]] = (0..<4).map { _ -> [asdf] in // expected-error {{use of undeclared type 'asdf'}} |
| 364 | + [UInt8](repeating: 0, count: width*height) |
| 365 | + } |
| 366 | +} |
| 367 | + |
| 368 | +// <rdar://problem/25993258> |
| 369 | +// Don't crash if we infer a closure argument to have a tuple type containing inouts. |
| 370 | +func r25993258_helper(_ fn: (inout Int, Int) -> ()) {} |
| 371 | +func r25993258a() { |
| 372 | + r25993258_helper { x in () } // expected-error {{contextual closure type '(inout Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} |
| 373 | +} |
| 374 | +func r25993258b() { |
| 375 | + r25993258_helper { _ in () } // expected-error {{contextual closure type '(inout Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} |
| 376 | +} |
| 377 | + |
| 378 | +// We have to map the captured var type into the right generic environment. |
| 379 | +class GenericClass<T> {} |
| 380 | + |
| 381 | +func lvalueCapture<T>(c: GenericClass<T>) { |
| 382 | + var cc = c |
| 383 | + weak var wc = c |
| 384 | + |
| 385 | + func innerGeneric<U>(_: U) { |
| 386 | + _ = cc |
| 387 | + _ = wc |
| 388 | + |
| 389 | + cc = wc! |
| 390 | + } |
| 391 | +} |
0 commit comments