// RUN: %target-typecheck-verify-swift -swift-version 6 func doStuff(_ fn : @escaping () -> Int) {} func doVoidStuff(_ fn : @escaping () -> ()) {} func doVoidStuffNonEscaping(_ fn: () -> ()) {} class ExplicitSelfRequiredTest { var x = 42 func method() -> Int { 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}} {{18-18= [self] in}} expected-note{{reference 'self.' explicitly}} {{29-29=self.}} doVoidStuff({ [self] in 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}} {{38-38= [self] in}} expected-note{{reference 'self.' explicitly}} {{39-39=self.}} return 42 } func weakSelfError() { doVoidStuff({ [weak self] in x += 1 }) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} doVoidStuffNonEscaping({ [weak self] in x += 1 }) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} doStuff({ [weak self] in x+1 }) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} doVoidStuff({ [weak self] in _ = method() }) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note{{reference 'self?.' explicitly}} doVoidStuffNonEscaping({ [weak self] in _ = method() }) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note{{reference 'self?.' explicitly}} doStuff({ [weak self] in method() }) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note{{reference 'self?.' explicitly}} } } // https://github.com/apple/swift/issues/56501 class C_56501 { func operation() {} func test1() { doVoidStuff { [self] in operation() } } func test2() { doVoidStuff { [self] in doVoidStuff { // expected-error@+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-error@+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 takesEscapingWithAllowedImplicitSelf(@_implicitSelfCapture _ fn: @escaping () -> Void) {} public final class TestImplicitSelfForWeakSelfCapture: Sendable { static let staticOptional: TestImplicitSelfForWeakSelfCapture? = .init() func method() { } private init() { doVoidStuff { [weak self] in method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} 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 ?? TestImplicitSelfForWeakSelfCapture.staticOptional else { return } method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } let otherValue = TestImplicitSelfForWeakSelfCapture.staticOptional ?? self doVoidStuff { [weak self = otherValue] in guard let 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 method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} guard let self = self else { return } method() } doVoidStuffNonEscaping { [weak self] in if let self = self { method() } } takesEscapingWithAllowedImplicitSelf { [weak self] in method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} guard let self = self else { return } method() } doVoidStuff { [weak self] in doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} 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}} expected-note{{reference 'self.' explicitly}} } } 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-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 } 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 } method() // expected-error {{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 {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} self?.method() } guard let self else { return } func innerFunction2() { method() self.method() } doVoidStuff { [self] in method() self.method() } } doVoidStuffNonEscaping { [weak self] in func innerFunction1() { method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} self?.method() } guard let self else { return } func innerFunction2() { method() self.method() } } } } class NoImplicitSelfInInnerClass { func method() { } private init() { // expected-note {{'self' declared here}} expected-note {{'self' declared here}} doVoidStuff { class InnerType { // expected-note {{type declared here}} 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'}} } } } doVoidStuff { [weak self] in guard let self else { return } method() class InnerType { // expected-note {{type declared here}} 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'}} } } } } 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() } } } class TestGithubIssue70089 { var x: Int = 0 nonisolated(unsafe) static let staticOptional: TestGithubIssue70089? = .init() func method() { } func f() { doVoidStuff { [weak self] in guard let self else { return } doVoidStuff { [self] in x += 1 } 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'}} expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} 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 { 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 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 {{capture 'self' explicitly to enable implicit 'self' in this closure}} 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}} 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 x += 1 self.x += 1 } } } doVoidStuff { [weak self] in doVoidStuff { x += 1 // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note{{reference 'self?.' explicitly}} self?.x += 1 } } doVoidStuff { [weak self] in doVoidStuffNonEscaping { x += 1 // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note{{reference 'self?.' explicitly}} 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 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 // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} doVoidStuff { [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 } } } func testClosuresInsideWeakSelfNotUnwrapped() { // https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230/1 doVoidStuff { [weak self] in doVoidStuff { [weak self] in guard let self else { return } x += 1 } } doVoidStuff { [weak self] in doVoidStuff { [weak self] in doVoidStuff { [weak self] in guard let self else { return } doVoidStuff { [weak self] in doVoidStuff { [weak self] in guard let self else { return } x += 1 } } } } } doVoidStuff { [weak self] in doVoidStuff { [weak self] in guard let self else { return } doVoidStuff { [self] in doVoidStuff { [self] in doVoidStuff { [weak self] in guard let self else { return } x += 1 } } } } } doVoidStuff { [weak self] in guard let self = self ?? TestGithubIssue70089.staticOptional else { return } doVoidStuff { [weak self] in guard let self else { return } x += 1 // expected-error{{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} } } doVoidStuff { [weak self] in doVoidStuff { [self] in // expected-error {{value of optional type 'TestGithubIssue70089?' must be unwrapped to a value of type 'TestGithubIssue70089'}} // expected-note@-1 {{coalesce using '??' to provide a default when the optional value contains 'nil'}} // expected-note@-2 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} x += 1 } } doVoidStuff { [weak self] in doVoidStuff { [self] in // expected-error {{value of optional type 'TestGithubIssue70089?' must be unwrapped to a value of type 'TestGithubIssue70089'}} // expected-note@-1 {{coalesce using '??' to provide a default when the optional value contains 'nil'}} // expected-note@-2 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} self.x += 1 } } doVoidStuff { [weak self] in doVoidStuff { [self] in self?.x += 1 } } doVoidStuff { [weak self] in doVoidStuff { [self] in guard let self else { return } self.x += 1 } } doVoidStuff { [weak self] in doVoidStuff { [self] in guard let self else { return } x += 1 } } doVoidStuff { [weak self] in guard let self = self ?? TestGithubIssue70089.staticOptional else { return } doVoidStuff { [self] in guard let self else { return } // expected-error{{initializer for conditional binding must have Optional type, not 'TestGithubIssue70089'}} x += 1 // expected-error{{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} } } } } class TestGithubIssue69911 { var x: Int = 0 nonisolated(unsafe) static let staticOptional: TestGithubIssue69911? = .init() func f() { doVoidStuff { [weak self] in guard let self else { return } doVoidStuffNonEscaping { x += 1 self.x += 1 } doVoidStuffNonEscaping { doVoidStuffNonEscaping { x += 1 self.x += 1 } } doVoidStuff { [self] in doVoidStuffNonEscaping { x += 1 self.x += 1 } } doVoidStuffNonEscaping { [self] in doVoidStuffNonEscaping { [self] in x += 1 self.x += 1 } } doVoidStuffNonEscaping { [self = TestGithubIssue69911()] in // expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} expected-note {{variable other than 'self' captured here under the name 'self' does not enable implicit 'self'}} 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 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 { [weak self] in doVoidStuffNonEscaping { [weak self] in x += 1 // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} 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 { // expected-note{{capture 'self' explicitly to enable implicit 'self' in this closure}} doVoidStuffNonEscaping { 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 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 // 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 doVoidStuffNonEscaping { doVoidStuffNonEscaping { doVoidStuff { [weak self] in self?.x += 1 guard let self else { return } x += 1 // expected-error{{reference to property 'x' in closure requires explicit use of 'self' to make capture semantics explicit}} 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 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 { // 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()) } doVoidStuffNonEscaping { [self] in withNonEscapingAutoclosure(bar()) } 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 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 withNonEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } doVoidStuff { [weak self] in withEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } doVoidStuff { [weak self] in doVoidStuff { withNonEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } doVoidStuff { [weak self] in doVoidStuff { withEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } doVoidStuff { [weak self] in doVoidStuff { [self] in withNonEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } doVoidStuff { [weak self] in doVoidStuff { [self] in withEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } doVoidStuff { [weak self] in guard let self else { return } 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 { // 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()) } doVoidStuffNonEscaping { [self] in withNonEscapingAutoclosure(bar()) } 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 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 guard let self else { return } method() } } 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 { let someOptional: Self? = Self() guard case let self = someOptional else { return } method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } doVoidStuff { [weak self] in let someOptional: Self? = Self() var `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 { method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuff { [self] in method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } 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}} } } } } 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'}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuffNonEscaping { [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}} } doVoidStuff() { [weak self] in guard let 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 guard let self else { return } method() // expected-error {{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'}} method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } doVoidStuffNonEscaping { [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}} } doVoidStuff() { [weak self] in guard let 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 guard let self else { return } method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } 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'}} 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-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}} } doVoidStuff() { [weak self] in guard let 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 guard let self else { return } method() // expected-error{{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}} } } } struct TestInvalidSelfCaptureInStruct { func method() { } func bar() { // To maintain source compatibility, we continue allowing this in Swift 5 mode: doVoidStuff { [self = TestInvalidSelfCaptureInStruct()] 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() } doVoidStuffNonEscaping { [self = TestInvalidSelfCaptureInStruct()] 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() } doVoidStuffNonEscaping { [self = TestInvalidSelfCaptureInStruct()] 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() } } } // rdar://129475277 class rdar129475277 { func bar() -> Int { 0 } func method() {} func test1() { takesEscapingWithAllowedImplicitSelf { [weak self] in takesEscapingWithAllowedImplicitSelf { method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } takesEscapingWithAllowedImplicitSelf { [weak self] in takesEscapingWithAllowedImplicitSelf { doVoidStuffNonEscaping { withNonEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } } takesEscapingWithAllowedImplicitSelf { [weak self] in withNonEscapingAutoclosure(bar()) // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } func test2() { guard case let self: rdar129475277? = nil else { return } // expected-warning@-1 {{'guard' condition is always true, body is unreachable}} doVoidStuffNonEscaping { method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}} } } } class TestExtensionOnOptionalSelf { init() {} func bar() {} } extension TestExtensionOnOptionalSelf? { func foo() { _ = { [weak self] in foo() // expected-error {{implicit use of 'self' in closure; use 'self.' to make capture semantics explicit}} } _ = { foo() self.foo() self?.bar() } _ = { [weak self] in _ = { foo() // expected-error {{implicit use of 'self' in closure; use 'self.' to make capture semantics explicit}} self.foo() self?.bar() } } _ = { [weak self] in _ = { [self] in foo() self.foo() self?.bar() } } } } // non-optional self in this extension, but on a type with members defined on optional self extension TestExtensionOnOptionalSelf { func foo() { _ = { [weak self] in foo() // expected-error {{implicit use of 'self' in closure; use 'self.' to make capture semantics explicit}} self.foo() self?.bar() } _ = { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}} foo() // expected-error {{call to method 'foo' in closure requires explicit use of 'self' to make capture semantics explicit}} expected-note {{reference 'self.' explicitly}} self.foo() } _ = { [weak self] in _ = { foo() // expected-error {{implicit use of 'self' in closure; use 'self.' to make capture semantics explicit}} self.foo() } } _ = { [weak self] in _ = { [self] in foo() self.foo() } } _ = { [weak self] in _ = { [self] in _ = { [self] in foo() self.foo() } } } _ = { [weak self] in doVoidStuffNonEscaping { _ = { [self] in foo() self.foo() } } } _ = { [weak self] in guard case let self = self else { return } _ = { [self] in foo() } } } } actor TestActor { func setUp() { doVoidStuff { [weak self] in Task { [weak self] in guard let self else { return } await test() } } } @MainActor func test() { } } class C { func foo() { _ = { [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}} guard case let self = C() else { return } _ = { [self] in foo() // expected-error {{call to method 'foo' in closure requires explicit use of 'self' to make capture semantics explicit}} } } } }