Skip to content

Commit f8ca293

Browse files
committed
Disable SE-0365 behavior for escaping closues in Swift 5 mode
1 parent e7512dc commit f8ca293

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,20 @@ static bool closureHasWeakSelfCapture(const AbstractClosureExpr *ACE) {
15381538
return false;
15391539
}
15401540

1541+
/// Whether or not this closure with a `weak self` capture is permitted
1542+
/// to use implicit self. We can't permit this for escaping closures in
1543+
/// Swift 5 mode, because the implicit self AST in Swift 5 would cause
1544+
/// self to be captured strongly instead of weakly.
1545+
static bool
1546+
allowsImplicitSelfForWeakSelfCapture(const AbstractClosureExpr *ACE) {
1547+
if (ACE->getASTContext().LangOpts.isSwiftVersionAtLeast(6)) {
1548+
return true;
1549+
}
1550+
1551+
return AnyFunctionRef(const_cast<AbstractClosureExpr *>(ACE))
1552+
.isKnownNoEscape();
1553+
}
1554+
15411555
/// Whether or not implicit self decls in this closure require manual
15421556
/// lookup in order to perform diagnostics with the semantics described
15431557
/// in SE-0365. This is necessary for closures that capture self weakly
@@ -1640,7 +1654,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
16401654
// let self = .someOptionalVariable else { return }` or `let self =
16411655
// someUnrelatedVariable`. If self hasn't been unwrapped yet and is still
16421656
// an optional, we would have already hit an error elsewhere.
1643-
if (closureHasWeakSelfCapture(inClosure)) {
1657+
if (closureHasWeakSelfCapture(inClosure) &&
1658+
allowsImplicitSelfForWeakSelfCapture(inClosure)) {
16441659
return !implicitWeakSelfReferenceIsValid(DRE, inClosure);
16451660
}
16461661

test/expr/closure/closures.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -749,21 +749,21 @@ public class TestImplicitSelfForWeakSelfCapture {
749749
doVoidStuff { [weak self] in
750750
method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
751751
guard let self = self else { return }
752-
method()
752+
method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
753753
}
754754

755755
doVoidStuff { [weak self] in
756756
guard let self else { return }
757-
method()
757+
method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
758758
}
759759

760760
doVoidStuff { [weak self] in
761761
if let self = self {
762-
method()
762+
method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
763763
}
764764

765765
if let self {
766-
method()
766+
method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
767767
}
768768
}
769769

0 commit comments

Comments
 (0)