Skip to content

Commit eb92e6e

Browse files
authored
Merge pull request #73997 from hamishknight/implicit-self-fix-6.0
[6.0] [Sema] Preserve compatibility for `weak self` with `@_implicitSelfCapture`
2 parents 996b4a8 + 1458f3c commit eb92e6e

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,6 +2415,13 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
24152415
return true;
24162416
}
24172417

2418+
// Implicit self was also permitted for weak self captures in closures
2419+
// passed to @_implicitSelfCapture parameters in Swift 5.7.
2420+
if (auto *CE = dyn_cast<ClosureExpr>(ACE)) {
2421+
if (CE->allowsImplicitSelfCapture())
2422+
return true;
2423+
}
2424+
24182425
// Invalid captures like `[weak self = somethingElse]`
24192426
// were permitted in Swift 5.8, so we must only warn.
24202427
if (!isSimpleSelfCapture(weakSelfDecl)) {

test/expr/closure/closures.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,8 @@ public class TestImplicitCaptureOfExplicitCaptureOfSelfInEscapingClosure {
756756
}
757757
}
758758

759+
func takesEscapingWithAllowedImplicitSelf(@_implicitSelfCapture _ fn: @escaping () -> Void) {}
760+
759761
public class TestImplicitSelfForWeakSelfCapture {
760762
static let staticOptional: TestImplicitSelfForWeakSelfCapture? = nil
761763
func method() { }
@@ -817,7 +819,13 @@ public class TestImplicitSelfForWeakSelfCapture {
817819
method()
818820
}
819821
}
820-
822+
823+
takesEscapingWithAllowedImplicitSelf { [weak self] in
824+
method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
825+
guard let self = self else { return }
826+
method()
827+
}
828+
821829
doVoidStuff { [weak self] in
822830
let `self`: TestImplicitSelfForWeakSelfCapture? = self ?? TestImplicitSelfForWeakSelfCapture.staticOptional
823831
guard let self = self else { return }
@@ -1743,4 +1751,4 @@ struct TestAsyncLetInStruct {
17431751
async let _ = bar()
17441752
}
17451753
}
1746-
}
1754+
}

test/expr/closure/closures_swift6.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class C_56501 {
8181
}
8282
}
8383

84+
func takesEscapingWithAllowedImplicitSelf(@_implicitSelfCapture _ fn: @escaping () -> Void) {}
85+
8486
public final class TestImplicitSelfForWeakSelfCapture: Sendable {
8587
static let staticOptional: TestImplicitSelfForWeakSelfCapture? = .init()
8688
func method() { }
@@ -130,6 +132,12 @@ public final class TestImplicitSelfForWeakSelfCapture: Sendable {
130132
}
131133
}
132134

135+
takesEscapingWithAllowedImplicitSelf { [weak self] in
136+
method() // expected-error {{explicit use of 'self' is required when 'self' is optional, to make control flow explicit}} expected-note {{reference 'self?.' explicitly}}
137+
guard let self = self else { return }
138+
method()
139+
}
140+
133141
doVoidStuff { [weak self] in
134142
doVoidStuff { // expected-note {{capture 'self' explicitly to enable implicit 'self' in this closure}}
135143
guard let self = self else { return }
@@ -796,4 +804,4 @@ struct TestInvalidSelfCaptureInStruct {
796804
self.method()
797805
}
798806
}
799-
}
807+
}

0 commit comments

Comments
 (0)