mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Swift has diagnosed implicit uses of class-reference `self` in escaping closures for a long time as potentially leading to reference cycles. PR #35898 fixed a bug where we failed to diagnose this condition in nested closures. Unfortunately, treating this as an error has proven problematic because there's a lot of code doing it. Requiring that code to be thoroughly stamped out before we ship a compiler is just too much to ask. Stage the fix in by treating it as a warning in Swift versions prior to 6. As with the non-nested case, this warning can be suppressed by explicitly either capturing `self` or spelling out `self.` in the access. Fixes rdar://80847025.
71 lines
1.8 KiB
Swift
71 lines
1.8 KiB
Swift
// 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() {
|
|
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.}}
|
|
}
|
|
}
|
|
|
|
class SR14120 {
|
|
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()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|