// RUN: %target-typecheck-verify-swift -disable-availability-checking var func6 : (_ fn : (Int,Int) -> Int) -> () var func6a : ((Int, Int) -> Int) -> () var func6b : (Int, (Int, Int) -> Int) -> () func func6c(_ f: (Int, Int) -> Int, _ n: Int = 0) {} // Expressions can be auto-closurified, so that they can be evaluated separately // from their definition. var closure1 : () -> Int = {4} // Function producing 4 whenever it is called. 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}} var closure3a : () -> () -> (Int,Int) = {{ (4, 2) }} // multi-level closing. 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 }} // expected-error@-1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{53-53= _ in}} var closure4 : (Int,Int) -> Int = { $0 + $1 } var closure5 : (Double) -> Int = { $0 + 1.0 // expected-error@-1 {{cannot convert value of type 'Double' to closure result type 'Int'}} } var closure6 = $0 // expected-error {{anonymous closure argument not contained in a closure}} 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=}} var capturedVariable = 1 var closure8 = { [capturedVariable] in capturedVariable += 1 // expected-error {{left side of mutating operator isn't mutable: 'capturedVariable' is an immutable capture}} } func funcdecl1(_ a: Int, _ y: Int) {} func funcdecl3() -> Int {} func funcdecl4(_ a: ((Int) -> Int), _ b: Int) {} func funcdecl5(_ a: Int, _ y: Int) { // Pass in a closure containing the call to funcdecl3. funcdecl4({ funcdecl3() }, 12) // expected-error {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{14-14= _ in}} func6({$0 + $1}) // Closure with two named anonymous arguments func6({($0) + $1}) // Closure with sequence expr inferred type func6({($0) + $0}) // // expected-error {{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 1 was used in closure body}} var testfunc : ((), Int) -> Int // expected-note 2 {{'testfunc' declared here}} testfunc({$0+1}) // expected-error {{missing argument for parameter #2 in call}} // expected-error@-1 {{closure passed to parameter of type '()' that does not accept a closure}} funcdecl5(1, 2) // recursion. // Element access from a tuple. var a : (Int, f : Int, Int) var b = a.1+a.f // Tuple expressions with named elements. var i : (y : Int, x : Int) = (x : 42, y : 11) // expected-warning {{expression shuffles the elements of this tuple; this behavior is deprecated}} funcdecl1(123, 444) // Calls. 4() // expected-error {{cannot call value of non-function type 'Int'}}{{4-6=}} // rdar://12017658 - Infer some argument types from func6. func6({ a, b -> Int in a+b}) // Return type inference. func6({ a,b in a+b }) // Infer incompatible type. 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. func6({ _,_ in 4 }) func6({a,b in 4.0 }) // expected-error {{cannot convert value of type 'Double' to closure result type 'Int'}} // TODO: This diagnostic can be improved: rdar://22128205 func6({(a : Float, b) in 4 }) // expected-error {{cannot convert value of type '(Float, Int) -> Int' to expected argument type '(Int, Int) -> Int'}} var fn = {} var fn2 = { 4 } var c : Int = { a,b -> Int in a+b} // expected-error{{cannot convert value of type '(Int, Int) -> Int' to specified type 'Int'}} } func unlabeledClosureArgument() { func add(_ x: Int, y: Int) -> Int { return x + y } func6a({$0 + $1}) // single closure argument func6a(add) func6b(1, {$0 + $1}) // second arg is closure func6b(1, add) func6c({$0 + $1}) // second arg is default int func6c(add) } // rdar://11935352 - closure with no body. func closure_no_body(_ p: () -> ()) { return closure_no_body({}) } // rdar://12019415 func t() { let u8 : UInt8 = 1 let x : Bool = true if 0xA0..<0xBF ~= Int(u8) && x { } } // func f0(_ a: Any) -> Int { return 1 } assert(f0(1) == 1) // TODO(diagnostics): Bad diagnostic - should be `circular reference` var selfRef = { selfRef() } // expected-error@-1 {{unable to infer closure type without a type annotation}} // TODO: should be an error `circular reference` but it's diagnosed via overlapped requests var nestedSelfRef = { var recursive = { nestedSelfRef() } // expected-warning@-1 {{variable 'recursive' was never mutated; consider changing to 'let' constant}} recursive() } var shadowed = { (shadowed: Int) -> Int in let x = shadowed return x } // no-warning var shadowedShort = { (shadowedShort: Int) -> Int in shadowedShort+1 } // no-warning func anonymousClosureArgsInClosureWithArgs() { func f(_: String) {} var a1 = { () in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} var a2 = { () -> Int in $0 } // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} 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}} var a4 = { (z: [Int], w: [Int]) in 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'}} 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}} } var a5 = { (_: [Int], w: [Int]) in f($0.count) // expected-error {{anonymous closure arguments cannot be used inside a closure that has explicit arguments}} 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}} } } func doStuff(_ fn : @escaping () -> Int) {} func doVoidStuff(_ fn : @escaping () -> ()) {} func doVoidStuffNonEscaping(_ fn: () -> ()) {} // Require specifying self for locations in code where strong reference cycles are likely class ExplicitSelfRequiredTest { var x = 42 func method() -> Int { // explicit closure requires an explicit "self." base or an explicit capture. doVoidStuff({ self.x += 1 }) doVoidStuff({ [self] in x += 1 }) doVoidStuff({ [self = self] in x += 1 }) doVoidStuff({ [unowned self] in x += 1 }) doVoidStuff({ [unowned(unsafe) self] in x += 1 }) doVoidStuff({ [unowned self = self] in x += 1 }) doStuff({ [self] in x+1 }) doStuff({ [self = self] in x+1 }) doStuff({ self.x+1 }) doStuff({ [unowned self] in x+1 }) doStuff({ [unowned(unsafe) self] in x+1 }) doStuff({ [unowned self = self] in x+1 }) doStuff({ x+1 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} expected-note{{reference 'self.' explicitly}} {{15-15=self.}} doVoidStuff({ doStuff({ x+1 })}) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{28-28= [self] in}} expected-note{{reference 'self.' explicitly}} {{29-29=self.}} doVoidStuff({ [self] in doStuff({ x+1 })}) // expected-warning {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{38-38= [self] in}} expected-note{{reference 'self.' explicitly}} {{39-39=self.}} doVoidStuff({ x += 1 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{19-19=self.}} doVoidStuff({ _ = "\(x)"}) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} doVoidStuff({ [y = self] in x += 1 }) // expected-warning {{capture 'y' was never used}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{20-20=self, }} expected-note{{reference 'self.' explicitly}} {{33-33=self.}} doStuff({ [y = self] in x+1 }) // expected-warning {{capture 'y' was never used}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} expected-note{{reference 'self.' explicitly}} {{29-29=self.}} doVoidStuff({ [self = ExplicitSelfRequiredTest()] in x += 1 }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{capture 'self' was never used}} doStuff({ [self = ExplicitSelfRequiredTest()] in x+1 }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{capture 'self' was never used}} // Methods follow the same rules as properties, uses of 'self' without capturing must be marked with "self." doStuff { method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} expected-note{{reference 'self.' explicitly}} {{15-15=self.}} doVoidStuff { _ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{23-23=self.}} doVoidStuff { _ = "\(method())" } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} doVoidStuff { () -> () in _ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self]}} expected-note{{reference 'self.' explicitly}} {{35-35=self.}} doVoidStuff { [y = self] in _ = method() } // expected-warning {{capture 'y' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{20-20=self, }} expected-note{{reference 'self.' explicitly}} {{37-37=self.}} doStuff({ [y = self] in method() }) // expected-warning {{capture 'y' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} expected-note{{reference 'self.' explicitly}} {{29-29=self.}} doVoidStuff({ [self = ExplicitSelfRequiredTest()] in _ = method() }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{capture 'self' was never used}} doStuff({ [self = ExplicitSelfRequiredTest()] in method() }) // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{capture 'self' was never used}} doVoidStuff { _ = self.method() } doVoidStuff { [self] in _ = method() } doVoidStuff { [self = self] in _ = method() } doVoidStuff({ [unowned self] in _ = method() }) doVoidStuff({ [unowned(unsafe) self] in _ = method() }) doVoidStuff({ [unowned self = self] in _ = method() }) doStuff { self.method() } doStuff { [self] in method() } doStuff({ [self = self] in method() }) doStuff({ [unowned self] in method() }) doStuff({ [unowned(unsafe) self] in method() }) doStuff({ [unowned self = self] in method() }) // When there's no space between the opening brace and the first expression, insert it doStuff {method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in }} expected-note{{reference 'self.' explicitly}} {{14-14=self.}} doVoidStuff {_ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in }} expected-note{{reference 'self.' explicitly}} {{22-22=self.}} doVoidStuff {() -> () in _ = method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self]}} expected-note{{reference 'self.' explicitly}} {{34-34=self.}} // With an empty capture list, insertion should be suggested without a comma doStuff { [] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} expected-note{{reference 'self.' explicitly}} {{21-21=self.}} doStuff { [ ] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} expected-note{{reference 'self.' explicitly}} {{23-23=self.}} doStuff { [ /* This space intentionally left blank. */ ] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} expected-note{{reference 'self.' explicitly}} {{65-65=self.}} // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self}} doStuff { [ // Nothing in this capture list! ] in method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{9-9=self.}} } // An inserted capture list should be on the same line as the opening brace, immediately following it. // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} doStuff { method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} } // expected-note@+2 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} // Note: Trailing whitespace on the following line is intentional and should not be removed! doStuff { method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} } // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} doStuff { // We have stuff to do. method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} } // expected-note@+1 {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{14-14= [self] in}} doStuff {// We have stuff to do. method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{7-7=self.}} } // String interpolation should offer the diagnosis and fix-its at the expected locations doVoidStuff { _ = "\(method())" } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} doVoidStuff { _ = "\(x+1)" } // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{26-26=self.}} expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} {{18-18= [self] in}} // If we already have a capture list, self should be added to the list let y = 1 doStuff { [y] in method() } // expected-warning {{capture 'y' was never used}} expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} expected-note{{reference 'self.' explicitly}} {{22-22=self.}} doStuff { [ // expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} y // expected-warning {{capture 'y' was never used}} ] in method() } // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} {{14-14=self.}} // "self." shouldn't be required in the initializer expression in a capture list // This should not produce an error, "x" isn't being captured by the closure. doStuff({ [myX = x] in myX }) // This should produce an error, since x is used within the inner closure. doStuff({ [myX = {x}] in 4 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{23-23= [self] in }} expected-note{{reference 'self.' explicitly}} {{23-23=self.}} // expected-warning @-1 {{capture 'myX' was never used}} return 42 } // The error emitted by these cases cause `VarDeclUsageChecker` to not run analysis on this method, // because its `sawError` flag is set to true. To preserve the "capture 'y' was never used" warnings // above, we put these cases in their own method. func weakSelfError() { doVoidStuff({ [weak self] in x += 1 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{variable 'self' was written to, but never read}} doVoidStuffNonEscaping({ [weak self] in x += 1 }) // expected-warning {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{variable 'self' was written to, but never read}} doStuff({ [weak self] in x+1 }) // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{variable 'self' was written to, but never read}} doVoidStuff({ [weak self] in _ = method() }) // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{variable 'self' was written to, but never read}} doVoidStuffNonEscaping({ [weak self] in _ = method() }) // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{variable 'self' was written to, but never read}} doStuff({ [weak self] in method() }) // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-warning {{variable 'self' was written to, but never read}} } } // If the implicit self is of value type, no diagnostic should be produced. struct ImplicitSelfAllowedInStruct { var x = 42 mutating func method() -> Int { doStuff({ x+1 }) doVoidStuff({ x += 1 }) doStuff({ method() }) doVoidStuff({ _ = method() }) } func method2() -> Int { doStuff({ x+1 }) doVoidStuff({ _ = x+1 }) doStuff({ method2() }) doVoidStuff({ _ = method2() }) } } enum ImplicitSelfAllowedInEnum { case foo var x: Int { 42 } mutating func method() -> Int { doStuff({ x+1 }) doVoidStuff({ _ = x+1 }) doStuff({ method() }) doVoidStuff({ _ = method() }) } func method2() -> Int { doStuff({ x+1 }) doVoidStuff({ _ = x+1 }) doStuff({ method2() }) doVoidStuff({ _ = method2() }) } } class SomeClass { var field : SomeClass? var `class` : SomeClass? var `in`: Int = 0 func foo() -> Int {} } func testCaptureBehavior(_ ptr : SomeClass) { // Test normal captures. weak var wv : SomeClass? = ptr unowned let uv : SomeClass = ptr unowned(unsafe) let uv1 : SomeClass = ptr unowned(safe) let uv2 : SomeClass = ptr doStuff { wv!.foo() } doStuff { uv.foo() } doStuff { uv1.foo() } doStuff { uv2.foo() } // Capture list tests let v1 : SomeClass? = ptr let v2 : SomeClass = ptr doStuff { [weak v1] in v1!.foo() } doStuff { [weak v1, // expected-note {{previous}} weak v1] in v1!.foo() } // expected-error {{invalid redeclaration of 'v1'}} doStuff { [unowned v2] in v2.foo() } doStuff { [unowned(unsafe) v2] in v2.foo() } doStuff { [unowned(safe) v2] in v2.foo() } doStuff { [weak v1, weak v2] in v1!.foo() + v2!.foo() } let i = 42 doStuff { [weak i] in i! } // expected-error {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}} } extension SomeClass { func bar() { doStuff { [unowned self] in self.foo() } doStuff { [unowned xyz = self.field!] in xyz.foo() } doStuff { [weak xyz = self.field] in xyz!.foo() } // rdar://16889886 - Assert when trying to weak capture a property of self in a lazy closure doStuff { [weak self.field] in field!.foo() } // expected-error@-1{{fields may only be captured by assigning to a specific name}}{{21-21=field = }} // expected-error@-2{{reference to property 'field' in closure requires explicit use of 'self' to make capture semantics explicit}} // expected-note@-3{{reference 'self.' explicitly}} {{36-36=self.}} // expected-note@-4{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} doStuff { [self.field] in field!.foo() } // expected-error@-1{{fields may only be captured by assigning to a specific name}}{{16-16=field = }} // expected-error@-2{{reference to property 'field' in closure requires explicit use of 'self' to make capture semantics explicit}} // expected-note@-3{{reference 'self.' explicitly}} {{31-31=self.}} // expected-note@-4{{capture 'self' explicitly to enable implicit 'self' in this closure}} {{16-16=self, }} doStuff { [self.field!.foo()] in 32 } //expected-error@-1{{fields may only be captured by assigning to a specific name}} doStuff { [self.class] in self.class!.foo() } //expected-error@-1{{fields may only be captured by assigning to a specific name}}{{16-16=`class` = }} doStuff { [self.`in`] in `in` } //expected-note@-1{{capture 'self' explicitly to enable implicit 'self' in this closure}} //expected-error@-2{{fields may only be captured by assigning to a specific name}}{{16-16=`in` = }} //expected-error@-3{{reference to property 'in' in closure requires explicit use of 'self' to make capture semantics explicit}} //expected-note@-4{{reference 'self.' explicitly}} // expected-warning @+1 {{variable 'self' was written to, but never read}} doStuff { [weak self&field] in 42 } // expected-error {{expected ']' at end of capture list}} } func strong_in_capture_list() { // QOI: "[strong self]" in capture list generates unhelpful error message _ = {[strong self] () -> () in return } // expected-error {{expected 'weak', 'unowned', or no specifier in capture list}} } } // Observed variable in a closure triggers an assertion var closureWithObservedProperty: () -> () = { var a: Int = 42 { // expected-warning {{variable 'a' was never used; consider replacing with '_' or removing it}} willSet { _ = "Will set a to \(newValue)" } didSet { _ = "Did set a with old value of \(oldValue)" } } } ; {}() // expected-error{{top-level statement cannot begin with a closure expression}} // rdar://19179412 - Crash on valid code. func rdar19179412() -> (Int) -> Int { return { x in class A { let d : Int = 0 } return 0 } } // Test coercion of single-expression closure return types to void. func takesVoidFunc(_ f: () -> ()) {} var i: Int = 1 // expected-warning @+1 {{expression of type 'Int' is unused}} takesVoidFunc({i}) // expected-warning @+1 {{expression of type 'Int' is unused}} var f1: () -> () = {i} var x = {return $0}(1) func returnsInt() -> Int { return 0 } takesVoidFunc(returnsInt) // expected-error {{cannot convert value of type '() -> Int' to expected argument type '() -> ()'}} takesVoidFunc({() -> Int in 0}) // expected-error {{declared closure result 'Int' is incompatible with contextual type '()'}} {{22-25=()}} // These used to crash the compiler, but were fixed to support the implementation of rdar://problem/17228969 Void(0) // expected-error{{argument passed to call that takes no arguments}} _ = {0} // "multi-statement closures require an explicit return type" should be an error not a note let samples = { if (i > 10) { return true } else { return false } }() // Swift error: cannot capture '$0' before it is declared func f(_ fp : (Bool, Bool) -> Bool) {} f { $0 && !$1 } // unexpected error on self. capture inside class method func TakesIntReturnsVoid(_ fp : ((Int) -> ())) {} struct TestStructWithStaticMethod { static func myClassMethod(_ count: Int) { // Shouldn't require "self." TakesIntReturnsVoid { _ in myClassMethod(0) } } } class TestClassWithStaticMethod { class func myClassMethod(_ count: Int) { // Shouldn't require "self." TakesIntReturnsVoid { _ in myClassMethod(0) } } } // Test that we can infer () as the result type of these closures. func genericOne(_ a: () -> T) {} func genericTwo(_ a: () -> T, _ b: () -> T) {} genericOne {} genericTwo({}, {}) // QoI: Warning for unused capture list variable should be customized class r22344208 { func f() { let q = 42 let _: () -> Int = { [unowned self, // expected-warning {{capture 'self' was never used}} q] in // expected-warning {{capture 'q' was never used}} 1 } } } var f = { (s: Undeclared) -> Int in 0 } // expected-error {{cannot find type 'Undeclared' in scope}} // Swift compiler crashes when using closure, declared to return illegal type. func r21375863() { var width = 0 var height = 0 var bufs: [[UInt8]] = (0..<4).map { _ -> [asdf] in // expected-error {{cannot find type 'asdf' in scope}} [UInt8](repeating: 0, count: width*height) } } // // Don't crash if we infer a closure argument to have a tuple type containing inouts. func r25993258_helper(_ fn: (inout Int, Int) -> ()) {} func r25993258a() { r25993258_helper { x in () } // expected-error {{contextual closure type '(inout Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} } func r25993258b() { r25993258_helper { _ in () } // expected-error {{contextual closure type '(inout Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} } // We have to map the captured var type into the right generic environment. class GenericClass {} func lvalueCapture(c: GenericClass) { var cc = c weak var wc = c func innerGeneric(_: U) { _ = cc _ = wc cc = wc! } } // Don't expose @lvalue-ness in diagnostics. let closure = { var helper = true // expected-warning {{variable 'helper' was never mutated; consider changing to 'let' constant}} return helper } // https://github.com/apple/swift/issues/52253 do { func f(_: @escaping @convention(block) () -> Void) {} func id(_: T) -> T {} let qux: () -> Void f(qux) f(id(qux)) // expected-error {{conflicting arguments to generic parameter 'T' ('() -> Void' vs. '@convention(block) () -> Void')}} func forceUnwrap(_: T?) -> T {} let qux1: (() -> Void)? f(qux1!) f(forceUnwrap(qux1)) } // rdar://problem/65155671 - crash referencing parameter of outer closure func rdar65155671(x: Int) { { a in _ = { [a] in a } }(x) } // https://github.com/apple/swift/issues/45774 do { func f(_: (@escaping (@escaping (T) -> U) -> ((T) -> U))) -> ((T) -> U) {} class C { init() { // expected-warning@+1{{capture 'self' was never used}} let _ = f { fn in { [unowned self, fn] x in x != 1000 ? fn(x + 1) : "success" } }(0) } } } // https://github.com/apple/swift/issues/56501 // Apply the explicit 'self' rule even if it refers to a capture, if // we're inside a nested closure. class C_56501 { func operation() {} func test1() { doVoidStuff { [self] in operation() } } func test2() { doVoidStuff { [self] in doVoidStuff { // expected-warning@+3 {{call to method 'operation' in closure requires explicit use of 'self'}} // expected-note@-2 {{capture 'self' explicitly to enable implicit 'self' in this closure}} // expected-note@+1 {{reference 'self.' explicitly}} operation() } } } func test3() { doVoidStuff { [self] in doVoidStuff { [self] in operation() } } } func test4() { doVoidStuff { [self] in doVoidStuff { self.operation() } } } func test5() { doVoidStuff { [self] in doVoidStuffNonEscaping { operation() } } } func test6() { doVoidStuff { [self] in doVoidStuff { [self] in doVoidStuff { // expected-warning@+3 {{call to method 'operation' in closure requires explicit use of 'self'}} // expected-note@-2 {{capture 'self' explicitly to enable implicit 'self' in this closure}} // expected-note@+1 {{reference 'self.' explicitly}} operation() } } } } func test7() { doVoidStuff { [self] in func innerFunction() { operation() } } } func test8() { doVoidStuffNonEscaping { [self] in func innerFunction() { operation() } } } } // https://github.com/apple/swift/issues/57029 do { func call(_ : Int, _ f: () -> (T, Int)) -> (T, Int) {} func f() -> (Int, Int) { call(1) { // expected-error {{cannot convert return expression of type '((), Int)' to return type '(Int, Int)'}} ((), 0) } } func f_Optional() -> (Int, Int)? { call(1) { // expected-error {{cannot convert return expression of type '((), Int)' to return type '(Int, Int)'}} ((), 0) } } } // https://github.com/apple/swift/issues/55680 func callit(_ f: () -> T) -> T { f() } func callitArgs(_ : Int, _ f: () -> T) -> T { f() } func callitArgsFn(_ : Int, _ f: () -> () -> T) -> T { f()() } func callitGenericArg(_ a: T, _ f: () -> T) -> T { f() } func callitTuple(_ : Int, _ f: () -> (T, Int)) -> T { f().0 } func callitVariadic(_ fs: () -> T...) -> T { fs.first!() } func test_55680_Tuple() -> Int { // expected-error@+2{{conflicting arguments to generic parameter 'T' ('()' vs. 'Int')}} // expected-note@+1:3{{generic parameter 'T' inferred as 'Int' from context}} callitTuple(1) { // expected-note@:18{{generic parameter 'T' inferred as '()' from closure return expression}} (print("hello"), 0) } } func test_55680() -> Int { // expected-error@+2{{conflicting arguments to generic parameter 'T' ('()' vs. 'Int')}} // expected-note@+1:3{{generic parameter 'T' inferred as 'Int' from context}} callit { // expected-note@:10{{generic parameter 'T' inferred as '()' from closure return expression}} print("hello") } } func test_55680_Args() -> Int { // expected-error@+2{{conflicting arguments to generic parameter 'T' ('()' vs. 'Int')}} // expected-note@+1:3{{generic parameter 'T' inferred as 'Int' from context}} callitArgs(1) { // expected-note@:17{{generic parameter 'T' inferred as '()' from closure return expression}} print("hello") } } func test_55680_ArgsFn() -> Int { // expected-error@+2{{conflicting arguments to generic parameter 'T' ('()' vs. 'Int')}} // expected-note@+1:3{{generic parameter 'T' inferred as 'Int' from context}} callitArgsFn(1) { // expected-note@:19{{generic parameter 'T' inferred as '()' from closure return expression}} { print("hello") } } } func test_55680_MultiExpr() -> Int { callit { print("hello") return print("hello") // expected-error {{cannot convert value of type '()' to closure result type 'Int'}} } } func test_55680_GenericArg() -> Int { // Generic argument is inferred as Int from first argument literal, so no conflict in this case. callitGenericArg(1) { print("hello") // expected-error {{cannot convert value of type '()' to closure result type 'Int'}} } } func test_55680_Variadic() -> Int { // expected-error@+2{{conflicting arguments to generic parameter 'T' ('()' vs. 'Int')}} // expected-note@+1:3{{generic parameter 'T' inferred as 'Int' from context}} callitVariadic({ // expected-note@:18{{generic parameter 'T' inferred as '()' from closure return expression}} print("hello") }) } func test_55680_Variadic_Twos() -> Int { // expected-error@+1{{cannot convert return expression of type '()' to return type 'Int'}} callitVariadic({ print("hello") }, { print("hello") }) } // rdar://82545600: this should just be a warning until Swift 6 public class TestImplicitCaptureOfExplicitCaptureOfSelfInEscapingClosure { var property = false private init() { doVoidStuff { [unowned self] in doVoidStuff {} doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} doVoidStuff {} property = false // expected-warning {{reference to property 'property' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } } } func takesEscapingWithAllowedImplicitSelf(@_implicitSelfCapture _ fn: @escaping () -> Void) {} public class TestImplicitSelfForWeakSelfCapture { static let staticOptional: TestImplicitSelfForWeakSelfCapture? = nil func method() { } private init(x: TestImplicitSelfForWeakSelfCapture) { doVoidStuff { [weak self] in method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} guard let self = self else { return } method() } doVoidStuff { [weak self] in guard let self else { return } method() } doVoidStuff { [weak self] in if let self = self { method() } if let self { method() } } doVoidStuff { [weak self] in guard let self = self else { return } doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuff { doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } doVoidStuff { [self] in // expected-warning {{capture 'self' was never used}} doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } } doVoidStuff { [weak self] in guard let self = self ?? TestImplicitSelfForWeakSelfCapture.staticOptional else { return } // expected-warning {{value 'self' was defined but never used; consider replacing with boolean test}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuffNonEscaping { [weak self] in method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} guard let self = self else { return } method() } doVoidStuffNonEscaping { [weak self] in if let self = self { method() } } takesEscapingWithAllowedImplicitSelf { [weak self] in method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} guard let self = self else { return } method() } doVoidStuff { [weak self] in let `self`: TestImplicitSelfForWeakSelfCapture? = self ?? TestImplicitSelfForWeakSelfCapture.staticOptional guard let self = self else { return } method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuffNonEscaping { [weak self] in let `self`: TestImplicitSelfForWeakSelfCapture? = self ?? TestImplicitSelfForWeakSelfCapture.staticOptional guard let self = self else { return } method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuffNonEscaping { [weak self] in guard let self = self else { return } // expected-warning {{value 'self' was defined but never used; consider replacing with boolean test}} doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } doVoidStuffNonEscaping { [weak self] in guard let self = self ?? TestImplicitSelfForWeakSelfCapture.staticOptional else { return } // expected-warning {{value 'self' was defined but never used; consider replacing with boolean test}} method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuff { [weak self] in func innerFunction1() { method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} self?.method() } guard let self else { return } func innerFunction2() { method() self.method() } subscript(index: Int) -> Int { // expected-error {{subscript' functions may only be declared within a type}} method() return index } } doVoidStuffNonEscaping { [weak self] in func innerFunction1() { method() // expected-warning{{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit; this is an error in the Swift 6 language mode}} self?.method() } guard let self else { return } func innerFunction2() { method() self.method() } subscript(index: Int) -> Int { // expected-error {{subscript' functions may only be declared within a type}} method() return index } } doVoidStuff { [weak self] in guard let self else { return } func innerFunction1() { doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} self.method() } doVoidStuff { [weak self] in method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} self?.method() } doVoidStuff { [weak self] in guard let self else { return } method() func innerMethod3() { method() self.method() } } } } } } class NoImplicitSelfInInnerClass { func method() { } private init() { // expected-note {{'self' declared here}} expected-note {{'self' declared here}} expected-note {{'self' declared here}} expected-note {{'self' declared here}} expected-note {{'self' declared here}} expected-note {{'self' declared here}} expected-note {{'self' declared here}} doVoidStuff { class InnerType { // expected-note {{type declared here}} expected-note {{type declared here}} expected-note {{type declared here}} init() { method() // expected-error {{class declaration cannot close over value 'self' defined in outer scope}} self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} } func functionInsideInnerType() { method() // expected-error {{class declaration cannot close over value 'self' defined in outer scope}} self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} } subscript(index: Int) -> Int { method() // expected-error {{class declaration cannot close over value 'self' defined in outer scope}} self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} return index } } } doVoidStuff { [weak self] in guard let self else { return } method() class InnerType { // expected-note {{type declared here}} expected-note {{type declared here}} expected-note {{type declared here}} func methodOnInnerType() { } init() { methodOnInnerType() method() // expected-error {{class declaration cannot close over value 'self' defined in outer scope}} self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} } func functionInsideInnerType() { methodOnInnerType() method() // expected-error {{class declaration cannot close over value 'self' defined in outer scope}} self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} } subscript(index: Int) -> Int { methodOnInnerType() method() // expected-error {{class declaration cannot close over value 'self' defined in outer scope}} self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} return index } } } doVoidStuff { [weak self] in guard let self else { return } func innerMethod() { method() class InnerType { // expected-note {{type declared here}} func methodOnInnerType() { } init() { methodOnInnerType() method() // expected-error {{class declaration cannot close over value 'self' defined in outer scope}} self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} doVoidStuff { [weak self] in guard let self else { return } self.method() // expected-error {{value of type 'InnerType' has no member 'method'}} methodOnInnerType() } doVoidStuff { [weak self] in guard let self else { return } method() // expected-error {{value of type 'InnerType' has no member 'method'}} methodOnInnerType() } } } } } } func foo(condition: Bool) { doVoidStuff { [weak self] in guard condition, let self else { return } method() } doVoidStuff { [weak self] in guard let self, condition else { return } method() } doVoidStuffNonEscaping { [weak self] in guard condition, let self else { return } method() } doVoidStuffNonEscaping { [weak self] in guard let self, condition else { return } method() } } func foo(optionalCondition: Bool?) { doVoidStuff { [weak self] in guard let optionalCondition, optionalCondition, let self else { return } method() } doVoidStuff { [weak self] in guard let self, let optionalCondition, optionalCondition else { return } method() } doVoidStuff { [weak self] in guard let optionalCondition, let self, optionalCondition else { return } method() } doVoidStuffNonEscaping { [weak self] in guard let optionalCondition, optionalCondition, let self else { return } method() } doVoidStuffNonEscaping { [weak self] in guard let self, let optionalCondition, optionalCondition else { return } method() } doVoidStuffNonEscaping { [weak self] in guard let optionalCondition, let self, optionalCondition else { return } method() } } func foo() { doVoidStuff { [weak self] in guard #available(SwiftStdlib 5.8, *), let self else { return } method() } doVoidStuff { [weak self] in guard let self, #available(SwiftStdlib 5.8, *) else { return } method() } doVoidStuffNonEscaping { [weak self] in guard #available(SwiftStdlib 5.8, *), let self else { return } method() } doVoidStuffNonEscaping { [weak self] in guard let self, #available(SwiftStdlib 5.8, *) else { return } method() } } } public class TestRebindingSelfIsDisallowed { let count: Void = () private init() { doVoidStuff { let `self` = "self shouldn't become a string" let _: Int = count // expected-error{{cannot convert value of type 'Void' to specified type 'Int'}} } doVoidStuffNonEscaping { let `self` = "self shouldn't become a string" let _: Int = count // expected-error{{cannot convert value of type 'Void' to specified type 'Int'}} } doVoidStuff { [weak self] in let `self` = "self shouldn't become a string" let _: Int = count // expected-error{{cannot convert value of type 'Void' to specified type 'Int'}} } doVoidStuffNonEscaping { [weak self] in let `self` = "self shouldn't become a string" let _: Int = count // expected-error{{cannot convert value of type 'Void' to specified type 'Int'}} } } func method() { let `self` = "self shouldn't become a string" let _: Int = count // expected-error{{cannot convert value of type 'Void' to specified type 'Int'}} } func testTypeNamedSelf() { struct `self` { static func staticMember() {} } doVoidStuff { staticMember() // expected-error{{cannot find 'staticMember' in scope}} self.staticMember() } doVoidStuffNonEscaping { staticMember() // expected-error{{cannot find 'staticMember' in scope}} self.staticMember() } doVoidStuff { [weak self] in staticMember() // expected-error{{cannot find 'staticMember' in scope}} self.staticMember() } doVoidStuffNonEscaping { [weak self] in staticMember() // expected-error{{cannot find 'staticMember' in scope}} self.staticMember() } doVoidStuff { [self] in staticMember() // expected-error{{cannot find 'staticMember' in scope}} self.staticMember() } } } // https://github.com/apple/swift/issues/59716 ["foo"].map { s in if s == "1" { return } // expected-error{{cannot convert value of type '()' to closure result type 'Bool'}} return s.isEmpty }.filter { $0 } ["foo"].map { s in if s == "1" { return } // expected-error{{cannot convert value of type '()' to closure result type 'Bool'}} if s == "2" { return } if s == "3" { return } return s.isEmpty }.filter { $0 } ["foo"].map { s in if s == "1" { return () } // expected-error{{cannot convert value of type '()' to closure result type 'Bool'}} return s.isEmpty }.filter { $0 } func producer(_ f: (String) -> T) -> T {} func f59716() -> some BinaryInteger { // expected-note{{required by opaque return type of global function 'f59716()'}} // expected-note@+1{{only concrete types such as structs, enums and classes can conform to protocols}} return producer { s in // expected-error{{type '()' cannot conform to 'BinaryInteger'}} if s == "1" { return } return s.count // expected-error{{cannot convert value of type 'Int' to closure result type '()'}} } } func f59716_1() -> some BinaryInteger { return producer { s in if s == "1" { return 1 } return s.count } } // https://github.com/apple/swift/issues/60781 func f60781(_ x: T) -> T { x } func f60781(_ x: T, _ y: T) -> T { x } func test60781() -> Int { f60781({ 1 }) // expected-error{{conflicting arguments to generic parameter 'T' ('Int' vs. '() -> Int')}} } func test60781_MultiArg() -> Int { f60781({ 1 }, { 1 }) // expected-error{{conflicting arguments to generic parameter 'T' ('Int' vs. '() -> Int')}} } @resultBuilder struct VoidBuilder { static func buildBlock() -> Void { } static func buildPartialBlock(first: T) -> Void { } static func buildPartialBlock(accumulated: Void, next: T) -> Void { } } final class EscapingWrapper { static func wrapper(_ closure: @escaping () -> Void) { closure() } } final class TestGithubIssue64757 { var instanceProperty: String = "instance property" @VoidBuilder var void: Void { EscapingWrapper.wrapper { [weak self] in print(instanceProperty) // expected-error {{reference to property 'instanceProperty' in closure requires explicit use of 'self' to make capture semantics explicit}} if let self { print(instanceProperty) } guard let self else { return } print(instanceProperty) } } } class TestGithubIssue70089 { var x: Int = 0 static let staticOptional: TestGithubIssue70089? = .init() func method() { } func f() { doVoidStuff { [weak self] in guard let self else { return } doVoidStuff { [self] in // expected-warning {{capture 'self' was never used}} expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuff { [self = TestGithubIssue70089()] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} x += 1 // expected-error{{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 doVoidStuff { // expected-note {{'self' explicitly to enable implicit 'self' in this closure}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} self.x += 1 } doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuff { [weak self] in x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self?.x += 1 } doVoidStuff { [weak self] in method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} self?.method() } doVoidStuff { doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} self.x += 1 } } doVoidStuff { [self] in doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} self.x += 1 } } doVoidStuff { doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } } doVoidStuff { [weak self] in doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} self?.x += 1 } } doVoidStuff { [weak self] in doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self?.x += 1 } } doVoidStuff { [weak self] in // Since this unwrapping is invalid, implicit self is disallowed in all nested closures: guard let self = self ?? TestGithubIssue70089.staticOptional else { return } doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuff { [self = TestGithubIssue70089()] in doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuff { [self] in doVoidStuff { doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} x += 1 // expected-warning {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} self.x += 1 } } } doVoidStuffNonEscaping { [self] in doVoidStuffNonEscaping { doVoidStuffNonEscaping { x += 1 self.x += 1 } } } } } class TestGithubIssue69911 { var x: Int = 0 static let staticOptional: TestGithubIssue69911? = .init() func f() { doVoidStuff { [weak self] in guard let self else { return } // This stops being an error in Swift 6 mode. doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } // This stops being an error in Swift 6 mode. doVoidStuffNonEscaping { doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } // This stops being an error in Swift 6 mode. doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } // This stops being an error in Swift 6 mode. doVoidStuffNonEscaping { [self] in doVoidStuffNonEscaping { [self] in x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuffNonEscaping { [weak self] in doVoidStuffNonEscaping { guard let self else { return } x += 1 // expected-warning {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuffNonEscaping { [self = TestGithubIssue69911()] in x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} x += 1 // expected-error{{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuffNonEscaping { [weak self] in x += 1 // expected-warning {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self?.x += 1 } } doVoidStuff { [weak self] in // Since this unwrapping is invalid, implicit self is disallowed in all nested closures: guard let self = self ?? TestGithubIssue69911.staticOptional else { return } doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } doVoidStuffNonEscaping { doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} doVoidStuffNonEscaping { x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuffNonEscaping { [self] in doVoidStuffNonEscaping { [self] in x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuffNonEscaping { [self = TestGithubIssue69911()] in x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } doVoidStuffNonEscaping { [weak self] in x += 1 // expected-warning {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self?.x += 1 } doVoidStuffNonEscaping { [self = TestGithubIssue69911()] in doVoidStuffNonEscaping { [self] in x += 1 // expected-error {{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} self.x += 1 } } doVoidStuff { [self] in doVoidStuffNonEscaping { doVoidStuffNonEscaping { doVoidStuff { [weak self] in self?.x += 1 guard let self else { return } x += 1 // This refers to the 'self' of the function self.x += 1 } } } } } } } func withNonEscapingAutoclosure(_ x: @autoclosure () -> T) {} func withEscapingAutoclosure(_ x: @escaping @autoclosure () -> T) {} final class AutoclosureTests { func bar() -> Bool { true } func method() { } func foo(_ x: AutoclosureTests) { withNonEscapingAutoclosure(bar()) withEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} << This is a false positive withNonEscapingAutoclosure(bar()) withEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} withNonEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuff { [self] in withNonEscapingAutoclosure(bar()) } doVoidStuffNonEscaping { withNonEscapingAutoclosure(bar()) } // NOTE: This is a false positive doVoidStuffNonEscaping { [self] in withNonEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuff { withEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuffNonEscaping { withEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuffNonEscaping { [self] in withEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } doVoidStuff { [weak self] in // expected-warning {{variable 'self' was written to, but never read}} withNonEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuff { [weak self] in // expected-warning {{variable 'self' was written to, but never read}} withEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuff { [weak self] in // expected-warning {{variable 'self' was written to, but never read}} doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} withNonEscapingAutoclosure(bar()) // expected-error {{all to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } doVoidStuff { [weak self] in // expected-warning {{variable 'self' was written to, but never read}} doVoidStuff { withEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } doVoidStuff { [weak self] in doVoidStuff { [self] in // expected-warning {{capture 'self' was never used}} expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} withNonEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} } } doVoidStuff { [weak self] in doVoidStuff { [self] in // expected-warning {{capture 'self' was never used}} withEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } doVoidStuff { [weak self] in guard let self else { return } withNonEscapingAutoclosure(bar()) withEscapingAutoclosure(bar()) doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} withNonEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuffNonEscaping { withNonEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuffNonEscaping { [self] in // expected-warning {{capture 'self' was never used}} withNonEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuff { withEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuffNonEscaping { withEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } doVoidStuffNonEscaping { [self] in // expected-warning {{capture 'self' was never used}} withEscapingAutoclosure(bar()) // expected-error {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } doVoidStuff { [weak self] in doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} guard let self else { return } // expected-warning {{value 'self' was defined but never used; consider replacing with boolean test}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } doVoidStuff { [weak self] in let someOptional: Self? = Self() let `self` = self ?? someOptional guard let self = self else { return } method() // expected-error{{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuff { [weak self] in let someOptional: Self? = Self() var `self` = self ?? someOptional // expected-warning {{'self' was never mutated; consider changing to 'let' constant}} guard let self = self else { return } // This is not supposed to be permitted, but has been allowed since Swift 5.8, // so we have to continue allowing it to maintain source compatibility. method() } doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} let someOptional: Self? = Self() guard case let self = someOptional else { return } // expected-warning {{immutable value 'self' was never used; consider replacing with '_' or removing it}} method() // expected-error{{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } // This isn't supposed to be accepted, but has been accepted since Swift 5.8 doVoidStuff { [weak self = x] in guard let self else { return } method() } doVoidStuff { [weak self] in doVoidStuff { [self] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} guard let self else { return } // expected-warning {{value 'self' was defined but never used; consider replacing with boolean test}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } doVoidStuff { [weak self] in doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} guard let self = self else { return } // expected-warning {{value 'self' was defined but never used; consider replacing with boolean test}} method() // expected-error{{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} } } } } class TestInvalidRebindingOutsideOfClosure { func method() { } func testInvalidRebindingCondition() { guard case let self = TestInvalidRebindingOutsideOfClosure() else { return } // expected-warning {{'guard' condition is always true, body is unreachable}} doVoidStuff { [self] in // expected-note{{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-warning {{capture 'self' was never used}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } // Allowed in Swift 5 mode for source compatibility: doVoidStuffNonEscaping { [self] in // expected-warning {{capture 'self' was never used}} method() } doVoidStuff() { [weak self] in guard let self else { return } method() } doVoidStuffNonEscaping() { [weak self] in guard let self else { return } method() } doVoidStuff { [weak self] in guard let self = self else { return } doVoidStuff { [self] in // expected-warning {{capture 'self' was never used}} expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } doVoidStuffNonEscaping { [weak self] in guard let self = self else { return } doVoidStuffNonEscaping { [self] in // expected-warning {{capture 'self' was never used}} method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } } func testInvalidSelfWithBackticks() { let `self` = TestInvalidRebindingOutsideOfClosure() doVoidStuff { [self] in // expected-note{{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-warning {{capture 'self' was never used}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } // Allowed in Swift 5 mode for source compatibility: doVoidStuffNonEscaping { [self] in // expected-warning {{capture 'self' was never used}} method() } doVoidStuff() { [weak self] in guard let self else { return } method() } doVoidStuffNonEscaping() { [weak self] in guard let self else { return } method() } } func testInvalidSelfWithBackticks2() { let `self` = self doVoidStuff { [self] in // expected-note{{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-warning {{capture 'self' was never used}} method() // expected-error{{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } // Allowed in Swift 5 mode for source compatibility: doVoidStuffNonEscaping { [self] in // expected-warning {{capture 'self' was never used}} method() } doVoidStuff() { [weak self] in guard let self else { return } method() } doVoidStuffNonEscaping() { [weak self] in guard let self else { return } method() } } } struct TestInvalidSelfCaptureInStruct { func method() { } func bar() { // To maintain source compatibility, we continue allowing this in Swift 5 mode: doVoidStuff { [self = TestInvalidSelfCaptureInStruct()] in method() // This refers to the 'self' of the function. self.method() } doVoidStuffNonEscaping { [self = TestInvalidSelfCaptureInStruct()] in method() // This refers to the 'self' of the function. self.method() } doVoidStuffNonEscaping { [self = TestInvalidSelfCaptureInStruct()] in method() // This refers to the 'self' of the function. self.method() } } } class TestAsyncLetInClass { init() { } func bar() -> Int { 0 } func foo() async { let _ = { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} async let _ = bar() // expected-error{{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note{{reference 'self.' explicitly}} } } } struct TestAsyncLetInStruct { func bar() -> Int { 0 } func foo() async { let _ = { async let _ = bar() } } } // rdar://129475277 class rdar129475277 { func bar() -> Int { 0 } func method() {} func test1() { takesEscapingWithAllowedImplicitSelf { [weak self] in // expected-warning {{variable 'self' was written to, but never read}} takesEscapingWithAllowedImplicitSelf { method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } takesEscapingWithAllowedImplicitSelf { [weak self] in // expected-warning {{variable 'self' was written to, but never read}} takesEscapingWithAllowedImplicitSelf { doVoidStuffNonEscaping { withNonEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} } } } takesEscapingWithAllowedImplicitSelf { [weak self] in // expected-warning {{variable 'self' was written to, but never read}} withNonEscapingAutoclosure(bar()) // expected-warning {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} } } func test2() { guard case let self: rdar129475277? = nil else { return } // expected-warning@-1 {{'guard' condition is always true, body is unreachable}} // expected-warning@-2 {{immutable value 'self' was never used}} doVoidStuffNonEscaping { method() } } } class TestLazyLocal { func bar() -> Int { 0 } func foo() { _ = { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} lazy var x = bar() // expected-error@-1 {{call to method 'bar' in closure requires explicit use of 'self' to make capture semantics explicit}} // expected-note@-2 {{reference 'self.' explicitly}} return x } } }