Skip to content

Commit 3e14028

Browse files
committed
Fix issue where non-pattern-binding condition would break SE-0365 unwrapped self check
1 parent 3be14e0 commit 3e14028

File tree

4 files changed

+161
-1
lines changed

4 files changed

+161
-1
lines changed

lib/AST/UnqualifiedLookup.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ bool implicitSelfReferenceIsUnwrapped(const ValueDecl *selfDecl,
400400
// Find the condition that defined the self decl,
401401
// and check that both its LHS and RHS are 'self'
402402
for (auto cond : conditionalStmt->getCond()) {
403+
if (cond.getKind() != StmtConditionElement::CK_PatternBinding) {
404+
continue;
405+
}
406+
403407
if (auto pattern = cond.getPattern()) {
404408
if (pattern->getBoundName() != Ctx.Id_self) {
405409
continue;

lib/Sema/MiscDiagnostics.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,10 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
17031703
// Find the condition that defined the self decl,
17041704
// and check that both its LHS and RHS are 'self'
17051705
for (auto cond : conditionalStmt->getCond()) {
1706+
if (cond.getKind() != StmtConditionElement::CK_PatternBinding) {
1707+
continue;
1708+
}
1709+
17061710
if (auto OSP = dyn_cast<OptionalSomePattern>(cond.getPattern())) {
17071711
if (OSP->getSubPattern()->getBoundName() != Ctx.Id_self) {
17081712
continue;

test/expr/closure/closures.swift

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,82 @@ public class TestImplicitSelfForWeakSelfCapture {
813813
method() // expected-warning {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
814814
}
815815
}
816+
817+
func foo(condition: Bool) {
818+
doVoidStuff { [weak self] in
819+
guard condition, let self else { return }
820+
method()
821+
}
822+
823+
doVoidStuff { [weak self] in
824+
guard let self, condition else { return }
825+
method()
826+
}
827+
828+
doVoidStuffNonEscaping { [weak self] in
829+
guard condition, let self else { return }
830+
method()
831+
}
832+
833+
doVoidStuffNonEscaping { [weak self] in
834+
guard let self, condition else { return }
835+
method()
836+
}
837+
}
838+
839+
func foo(optionalCondition: Bool?) {
840+
doVoidStuff { [weak self] in
841+
guard let optionalCondition, optionalCondition, let self else { return }
842+
method()
843+
}
844+
845+
doVoidStuff { [weak self] in
846+
guard let self, let optionalCondition, optionalCondition else { return }
847+
method()
848+
}
849+
850+
doVoidStuff { [weak self] in
851+
guard let optionalCondition, let self, optionalCondition else { return }
852+
method()
853+
}
854+
855+
doVoidStuffNonEscaping { [weak self] in
856+
guard let optionalCondition, optionalCondition, let self else { return }
857+
method()
858+
}
859+
860+
doVoidStuffNonEscaping { [weak self] in
861+
guard let self, let optionalCondition, optionalCondition else { return }
862+
method()
863+
}
864+
865+
doVoidStuffNonEscaping { [weak self] in
866+
guard let optionalCondition, let self, optionalCondition else { return }
867+
method()
868+
}
869+
}
870+
871+
func foo() {
872+
doVoidStuff { [weak self] in
873+
guard #available(SwiftStdlib 5.8, *), let self else { return }
874+
method()
875+
}
876+
877+
doVoidStuff { [weak self] in
878+
guard let self, #available(SwiftStdlib 5.8, *) else { return }
879+
method()
880+
}
881+
882+
doVoidStuffNonEscaping { [weak self] in
883+
guard #available(SwiftStdlib 5.8, *), let self else { return }
884+
method()
885+
}
886+
887+
doVoidStuffNonEscaping { [weak self] in
888+
guard let self, #available(SwiftStdlib 5.8, *) else { return }
889+
method()
890+
}
891+
}
816892
}
817893

818894
public class TestRebindingSelfIsDisallowed {

test/expr/closure/closures_swift6.swift

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,82 @@ public class TestImplicitSelfForWeakSelfCapture {
155155
method() // expected-error {{call to method 'method' in closure requires explicit use of 'self' to make capture semantics explicit}}
156156
}
157157
}
158+
159+
func foo(condition: Bool) {
160+
doVoidStuff { [weak self] in
161+
guard condition, let self else { return }
162+
method()
163+
}
164+
165+
doVoidStuff { [weak self] in
166+
guard let self, condition else { return }
167+
method()
168+
}
169+
170+
doVoidStuffNonEscaping { [weak self] in
171+
guard condition, let self else { return }
172+
method()
173+
}
174+
175+
doVoidStuffNonEscaping { [weak self] in
176+
guard let self, condition else { return }
177+
method()
178+
}
179+
}
180+
181+
func foo(optionalCondition: Bool?) {
182+
doVoidStuff { [weak self] in
183+
guard let optionalCondition, optionalCondition, let self else { return }
184+
method()
185+
}
186+
187+
doVoidStuff { [weak self] in
188+
guard let self, let optionalCondition, optionalCondition else { return }
189+
method()
190+
}
191+
192+
doVoidStuff { [weak self] in
193+
guard let optionalCondition, let self, optionalCondition else { return }
194+
method()
195+
}
196+
197+
doVoidStuffNonEscaping { [weak self] in
198+
guard let optionalCondition, optionalCondition, let self else { return }
199+
method()
200+
}
201+
202+
doVoidStuffNonEscaping { [weak self] in
203+
guard let self, let optionalCondition, optionalCondition else { return }
204+
method()
205+
}
206+
207+
doVoidStuffNonEscaping { [weak self] in
208+
guard let optionalCondition, let self, optionalCondition else { return }
209+
method()
210+
}
211+
}
212+
213+
func foo() {
214+
doVoidStuff { [weak self] in
215+
guard #available(SwiftStdlib 5.8, *), let self else { return }
216+
method()
217+
}
218+
219+
doVoidStuff { [weak self] in
220+
guard let self, #available(SwiftStdlib 5.8, *) else { return }
221+
method()
222+
}
223+
224+
doVoidStuffNonEscaping { [weak self] in
225+
guard #available(SwiftStdlib 5.8, *), let self else { return }
226+
method()
227+
}
228+
229+
doVoidStuffNonEscaping { [weak self] in
230+
guard let self, #available(SwiftStdlib 5.8, *) else { return }
231+
method()
232+
}
233+
}
158234
}
159235

160236
public class TestRebindingSelfIsDisallowed {
@@ -186,4 +262,4 @@ public class TestRebindingSelfIsDisallowed {
186262
let `self` = "self shouldn't become a string"
187263
let _: Int = count // expected-error{{cannot convert value of type 'Void' to specified type 'Int'}}
188264
}
189-
}
265+
}

0 commit comments

Comments
 (0)