@@ -1715,6 +1715,91 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
17151715 Closures.push_back (ACE);
17161716 }
17171717
1718+ static bool
1719+ implicitWeakSelfReferenceIsValid510 (const DeclRefExpr *DRE,
1720+ const AbstractClosureExpr *inClosure) {
1721+ ASTContext &Ctx = DRE->getDecl ()->getASTContext ();
1722+
1723+ // Check if the implicit self decl refers to a var in a conditional stmt
1724+ LabeledConditionalStmt *conditionalStmt = nullptr ;
1725+ if (auto var = dyn_cast<VarDecl>(DRE->getDecl ())) {
1726+ if (auto parentStmt = var->getParentPatternStmt ()) {
1727+ conditionalStmt = dyn_cast<LabeledConditionalStmt>(parentStmt);
1728+ }
1729+ }
1730+
1731+ if (!conditionalStmt) {
1732+ return false ;
1733+ }
1734+
1735+ // Require `LoadExpr`s when validating the self binding.
1736+ // This lets us reject invalid examples like:
1737+ //
1738+ // let `self` = self ?? .somethingElse
1739+ // guard let self = self else { return }
1740+ // method() // <- implicit self is not allowed
1741+ //
1742+ return conditionalStmt->rebindsSelf (Ctx, /* requiresCaptureListRef*/ false ,
1743+ /* requireLoadExpr*/ true );
1744+ }
1745+
1746+ static bool
1747+ isEnclosingSelfReference510 (VarDecl *var,
1748+ const AbstractClosureExpr *inClosure) {
1749+ if (var->isSelfParameter ())
1750+ return true ;
1751+
1752+ // Capture variables have a DC of the parent function.
1753+ if (inClosure && var->isSelfParamCapture () &&
1754+ var->getDeclContext () != inClosure->getParent ())
1755+ return true ;
1756+
1757+ return false ;
1758+ }
1759+
1760+ static bool
1761+ selfDeclAllowsImplicitSelf510 (DeclRefExpr *DRE, Type ty,
1762+ const AbstractClosureExpr *inClosure) {
1763+ // If this is an explicit `weak self` capture, then implicit self is
1764+ // allowed once the closure's self param is unwrapped. We need to validate
1765+ // that the unwrapped `self` decl specifically refers to an unwrapped copy
1766+ // of the closure's `self` param, and not something else like in `guard
1767+ // let self = .someOptionalVariable else { return }` or `let self =
1768+ // someUnrelatedVariable`. If self hasn't been unwrapped yet and is still
1769+ // an optional, we would have already hit an error elsewhere.
1770+ if (closureHasWeakSelfCapture (inClosure)) {
1771+ return implicitWeakSelfReferenceIsValid510 (DRE, inClosure);
1772+ }
1773+
1774+ // Metatype self captures don't extend the lifetime of an object.
1775+ if (ty->is <MetatypeType>())
1776+ return true ;
1777+
1778+ // If self does not have reference semantics, it is very unlikely that
1779+ // capturing it will create a reference cycle.
1780+ if (!ty->hasReferenceSemantics ())
1781+ return true ;
1782+
1783+ if (auto closureExpr = dyn_cast<ClosureExpr>(inClosure)) {
1784+ if (auto selfDecl = closureExpr->getCapturedSelfDecl ()) {
1785+ // If this capture is using the name `self` actually referring
1786+ // to some other variable (e.g. with `[self = "hello"]`)
1787+ // then implicit self is not allowed.
1788+ if (!selfDecl->isSelfParamCapture ()) {
1789+ return false ;
1790+ }
1791+ }
1792+ }
1793+
1794+ if (auto var = dyn_cast<VarDecl>(DRE->getDecl ())) {
1795+ if (!isEnclosingSelfReference510 (var, inClosure)) {
1796+ return true ;
1797+ }
1798+ }
1799+
1800+ return false ;
1801+ }
1802+
17181803 // / Whether or not implicit self is allowed for self decl
17191804 static bool
17201805 selfDeclAllowsImplicitSelf (Expr *E, const AbstractClosureExpr *inClosure) {
@@ -1731,6 +1816,11 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
17311816 if (!ty)
17321817 return true ;
17331818
1819+ // Prior to Swift 6, use the old validation logic.
1820+ auto &ctx = inClosure->getASTContext ();
1821+ if (!ctx.isSwiftVersionAtLeast (6 ))
1822+ return selfDeclAllowsImplicitSelf510 (DRE, ty, inClosure);
1823+
17341824 return selfDeclAllowsImplicitSelf (DRE->getDecl (), ty, inClosure,
17351825 /* validateParentClosures:*/ true ,
17361826 /* validateSelfRebindings:*/ true );
@@ -2063,8 +2153,9 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
20632153 // / Return true if this is a closure expression that will require explicit
20642154 // / use or capture of "self." for qualification of member references.
20652155 static bool
2066- isClosureRequiringSelfQualification (const AbstractClosureExpr *CE) {
2067- if (closureHasWeakSelfCapture (CE)) {
2156+ isClosureRequiringSelfQualification (const AbstractClosureExpr *CE,
2157+ bool ignoreWeakSelf = false ) {
2158+ if (!ignoreWeakSelf && closureHasWeakSelfCapture (CE)) {
20682159 return true ;
20692160 }
20702161
@@ -2110,9 +2201,20 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21102201
21112202 bool shouldWalkCaptureInitializerExpressions () override { return true ; }
21122203
2204+ bool shouldRecordClosure (const AbstractClosureExpr *E) {
2205+ // Record all closures in Swift 6 mode.
2206+ if (Ctx.isSwiftVersionAtLeast (6 ))
2207+ return true ;
2208+
2209+ // Only record closures requiring self qualification prior to Swift 6
2210+ // mode.
2211+ return isClosureRequiringSelfQualification (E);
2212+ }
2213+
21132214 PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
21142215 if (auto *CE = dyn_cast<AbstractClosureExpr>(E)) {
2115- Closures.push_back (CE);
2216+ if (shouldRecordClosure (CE))
2217+ Closures.push_back (CE);
21162218 }
21172219
21182220 // If we aren't in a closure, no diagnostics will be produced.
@@ -2144,7 +2246,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21442246 diag::property_use_in_closure_without_explicit_self,
21452247 baseName.getIdentifier ())
21462248 .warnUntilSwiftVersionIf (
2147- invalidImplicitSelfShouldOnlyWarn (MRE->getBase (), ACE), 6 );
2249+ invalidImplicitSelfShouldOnlyWarn510 (MRE->getBase (), ACE), 6 );
21482250 }
21492251
21502252 // Handle method calls with a specific diagnostic + fixit.
@@ -2159,12 +2261,13 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21592261 diag::method_call_in_closure_without_explicit_self,
21602262 MethodExpr->getDecl ()->getBaseIdentifier ())
21612263 .warnUntilSwiftVersionIf (
2162- invalidImplicitSelfShouldOnlyWarn (DSCE->getBase (), ACE), 6 );
2264+ invalidImplicitSelfShouldOnlyWarn510 (DSCE->getBase (), ACE),
2265+ 6 );
21632266 }
21642267
21652268 if (memberLoc.isValid ()) {
21662269 const AbstractClosureExpr *parentDisallowingImplicitSelf = nullptr ;
2167- if (selfDRE && selfDRE->getDecl ()) {
2270+ if (Ctx. isSwiftVersionAtLeast ( 6 ) && selfDRE && selfDRE->getDecl ()) {
21682271 parentDisallowingImplicitSelf = parentClosureDisallowingImplicitSelf (
21692272 selfDRE->getDecl (), selfDRE->getType (), ACE);
21702273 }
@@ -2173,11 +2276,11 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21732276 return Action::SkipNode (E);
21742277 }
21752278
2176- if (!selfDeclAllowsImplicitSelf (E, ACE))
2279+ if (!selfDeclAllowsImplicitSelf (E, ACE)) {
21772280 Diags.diagnose (E->getLoc (), diag::implicit_use_of_self_in_closure)
2178- .warnUntilSwiftVersionIf (invalidImplicitSelfShouldOnlyWarn (E, ACE),
2179- 6 );
2180-
2281+ .warnUntilSwiftVersionIf (
2282+ invalidImplicitSelfShouldOnlyWarn510 (E, ACE), 6 );
2283+ }
21812284 return Action::Continue (E);
21822285 }
21832286
@@ -2187,9 +2290,10 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21872290 return Action::Continue (E);
21882291 }
21892292
2190- assert (Closures.size () > 0 );
2191- Closures.pop_back ();
2192-
2293+ if (shouldRecordClosure (ACE)) {
2294+ assert (Closures.size () > 0 );
2295+ Closures.pop_back ();
2296+ }
21932297 return Action::Continue (E);
21942298 }
21952299
@@ -2367,132 +2471,28 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
23672471
23682472 // / Whether or not this invalid usage of implicit self should be a warning
23692473 // / in Swift 5 mode, to preserve source compatibility.
2370- bool invalidImplicitSelfShouldOnlyWarn (Expr *selfRef,
2371- AbstractClosureExpr *ACE) {
2474+ bool invalidImplicitSelfShouldOnlyWarn510 (Expr *selfRef,
2475+ AbstractClosureExpr *ACE) {
23722476 auto DRE = dyn_cast_or_null<DeclRefExpr>(selfRef);
2373- if (!DRE) {
2477+ if (!DRE)
23742478 return false ;
2375- }
23762479
23772480 auto selfDecl = dyn_cast_or_null<VarDecl>(DRE->getDecl ());
2378- auto ty = DRE->getType ();
2379- if (!selfDecl) {
2380- return false ;
2381- }
2382-
2383- if (isInTypePreviouslyLackingValidation (ty)) {
2384- return true ;
2385- }
2386-
2387- if (isPreviouslyPermittedWeakSelfUsage (ACE, selfDecl, ty)) {
2388- return true ;
2389- }
2390-
2391- if (isUsageAlwaysPreviouslyRejected (selfDecl)) {
2481+ if (!selfDecl)
23922482 return false ;
2393- }
2394-
2395- if (isPreviouslyPermittedStrongSelfUsage (selfDecl, ACE)) {
2396- return true ;
2397- }
2398-
2399- return false ;
2400- }
24012483
2402- bool isInTypePreviouslyLackingValidation (Type ty) {
2403- // We previously didn't validate captures at all in structs or metadata
2404- // types, so we must only warn in this case.
2405- return !ty->hasReferenceSemantics () || ty->is <MetatypeType>();
2406- }
2407-
2408- // / Checks if this usage of implicit self in a weak self closure
2409- // / was previously permitted in Swift 5.8.
2410- bool isPreviouslyPermittedWeakSelfUsage (AbstractClosureExpr *ACE,
2411- ValueDecl *selfDecl, Type ty) {
2412- auto weakSelfDecl = weakSelfCapture (ACE);
2413- if (!weakSelfDecl) {
2414- return false ;
2415- }
2416-
2417- // Implicit self was permitted for weak self captures in
2418- // non-escaping closures in Swift 5.7, so we must only warn.
2419- if (isNonEscaping (ACE)) {
2420- return true ;
2421- }
2422-
2423- // Implicit self was also permitted for weak self captures in closures
2424- // passed to @_implicitSelfCapture parameters in Swift 5.7.
2425- if (auto *CE = dyn_cast<ClosureExpr>(ACE)) {
2426- if (CE->allowsImplicitSelfCapture ())
2427- return true ;
2428- }
2429-
2430- // Invalid captures like `[weak self = somethingElse]`
2431- // were permitted in Swift 5.8, so we must only warn.
2432- if (!isSimpleSelfCapture (weakSelfDecl)) {
2433- return true ;
2434- }
2435-
2436- if (auto condStmt = parentConditionalStmt (selfDecl)) {
2437- auto isValidSelfRebinding = hasValidSelfRebinding (condStmt, Ctx);
2438-
2439- // Swfit 5.8 permitted implicit self without validating any
2440- // parent closures. If implicit self is only disallowed due to
2441- // an invalid parent, we must only warn.
2442- if (isValidSelfRebinding &&
2443- implicitSelfDisallowedDueToInvalidParent (selfDecl, ty, ACE)) {
2444- return true ;
2445- }
2446-
2447- // Swift 5.8 used `requiresLoadExpr` to validate self bindings.
2448- // If the binding is valid when only checking for a load expr,
2449- // then we must only warn.
2450- auto usesLoadExpr =
2451- condStmt->rebindsSelf (Ctx, /* requiresCaptureListRef*/ false ,
2452- /* requireLoadExpr*/ true );
2453-
2454- if (!isValidSelfRebinding && usesLoadExpr) {
2455- return true ;
2456- }
2457- }
2458-
2459- return false ;
2460- }
2461-
2462- // / Checks if this implicit self usage was always previously rejected as
2463- // / invalid, so can continue to be treated an error.
2464- bool isUsageAlwaysPreviouslyRejected (ValueDecl *selfDecl) {
2465- // If the self decl refers to a weak self unwrap condition
2466- // in some parent closure, then there is no source-compatibility
2467- // requirement to avoid an error.
2468- return hasValidSelfRebinding (parentConditionalStmt (selfDecl), Ctx);
2469- }
2470-
2471- // / Checks if this is a usage of implicit self in a strong self closure
2472- // / that was previously permitted in older versions like Swift 5.3.
2473- bool isPreviouslyPermittedStrongSelfUsage (VarDecl *selfDecl,
2474- AbstractClosureExpr *ACE) {
2475- // Implicit self was accidentially allowed in examples like this
2476- // in Swift 5.3-5.5, so check for this case and emit a warning
2477- // instead of an error:
2478- //
2479- // withEscaping { [self] in
2480- // withEscaping {
2481- // x += 1
2482- // }
2483- // }
2484- //
2485- bool isEscapingClosureWithExplicitSelfCapture = false ;
2486- if (!isNonEscaping (ACE)) {
2487- if (auto closureExpr = dyn_cast<ClosureExpr>(ACE)) {
2488- if (closureExpr->getCapturedSelfDecl ()) {
2489- isEscapingClosureWithExplicitSelfCapture = true ;
2490- }
2491- }
2484+ // If this implicit self decl is from a closure that captured self
2485+ // weakly, then we should always emit an error, since implicit self was
2486+ // only allowed starting in Swift 5.8 and later.
2487+ if (closureHasWeakSelfCapture (ACE)) {
2488+ // Implicit self was incorrectly permitted for weak self captures
2489+ // in non-escaping closures in Swift 5.7, so in that case we can
2490+ // only warn until Swift 6.
2491+ return !isClosureRequiringSelfQualification (ACE,
2492+ /* ignoreWeakSelf*/ true );
24922493 }
24932494
2494- return !selfDecl->isSelfParameter () &&
2495- !isEscapingClosureWithExplicitSelfCapture;
2495+ return !selfDecl->isSelfParameter ();
24962496 }
24972497 };
24982498
0 commit comments