Files
swift-mirror/test/expr/closure/closures_swift6.swift
John McCall 5eecc6ac07 Only warn about self capture in nested closures until Swift 6.
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.
2021-08-18 21:44:23 -04:00

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()
}
}
}
}
}