@@ -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
@@ -2102,9 +2193,20 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21022193
21032194 bool shouldWalkCaptureInitializerExpressions () override { return true ; }
21042195
2196+ bool shouldRecordClosure (const AbstractClosureExpr *E) {
2197+ // Record all closures in Swift 6 mode.
2198+ if (Ctx.isSwiftVersionAtLeast (6 ))
2199+ return true ;
2200+
2201+ // Only record closures requiring self qualification prior to Swift 6
2202+ // mode.
2203+ return isClosureRequiringSelfQualification (E);
2204+ }
2205+
21052206 PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
21062207 if (auto *CE = dyn_cast<AbstractClosureExpr>(E)) {
2107- Closures.push_back (CE);
2208+ if (shouldRecordClosure (CE))
2209+ Closures.push_back (CE);
21082210 }
21092211
21102212 // If we aren't in a closure, no diagnostics will be produced.
@@ -2136,7 +2238,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21362238 diag::property_use_in_closure_without_explicit_self,
21372239 baseName.getIdentifier ())
21382240 .warnUntilSwiftVersionIf (
2139- invalidImplicitSelfShouldOnlyWarn (MRE->getBase (), ACE), 6 );
2241+ invalidImplicitSelfShouldOnlyWarn510 (MRE->getBase (), ACE), 6 );
21402242 }
21412243
21422244 // Handle method calls with a specific diagnostic + fixit.
@@ -2151,12 +2253,13 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21512253 diag::method_call_in_closure_without_explicit_self,
21522254 MethodExpr->getDecl ()->getBaseIdentifier ())
21532255 .warnUntilSwiftVersionIf (
2154- invalidImplicitSelfShouldOnlyWarn (DSCE->getBase (), ACE), 6 );
2256+ invalidImplicitSelfShouldOnlyWarn510 (DSCE->getBase (), ACE),
2257+ 6 );
21552258 }
21562259
21572260 if (memberLoc.isValid ()) {
21582261 const AbstractClosureExpr *parentDisallowingImplicitSelf = nullptr ;
2159- if (selfDRE && selfDRE->getDecl ()) {
2262+ if (Ctx. isSwiftVersionAtLeast ( 6 ) && selfDRE && selfDRE->getDecl ()) {
21602263 parentDisallowingImplicitSelf = parentClosureDisallowingImplicitSelf (
21612264 selfDRE->getDecl (), selfDRE->getType (), ACE);
21622265 }
@@ -2165,11 +2268,11 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21652268 return Action::SkipNode (E);
21662269 }
21672270
2168- if (!selfDeclAllowsImplicitSelf (E, ACE))
2271+ if (!selfDeclAllowsImplicitSelf (E, ACE)) {
21692272 Diags.diagnose (E->getLoc (), diag::implicit_use_of_self_in_closure)
2170- .warnUntilSwiftVersionIf (invalidImplicitSelfShouldOnlyWarn (E, ACE),
2171- 6 );
2172-
2273+ .warnUntilSwiftVersionIf (
2274+ invalidImplicitSelfShouldOnlyWarn510 (E, ACE), 6 );
2275+ }
21732276 return Action::Continue (E);
21742277 }
21752278
@@ -2179,9 +2282,10 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21792282 return Action::Continue (E);
21802283 }
21812284
2182- assert (Closures.size () > 0 );
2183- Closures.pop_back ();
2184-
2285+ if (shouldRecordClosure (ACE)) {
2286+ assert (Closures.size () > 0 );
2287+ Closures.pop_back ();
2288+ }
21852289 return Action::Continue (E);
21862290 }
21872291
@@ -2359,134 +2463,28 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
23592463
23602464 // / Whether or not this invalid usage of implicit self should be a warning
23612465 // / in Swift 5 mode, to preserve source compatibility.
2362- bool invalidImplicitSelfShouldOnlyWarn (Expr *selfRef,
2363- AbstractClosureExpr *ACE) {
2466+ bool invalidImplicitSelfShouldOnlyWarn510 (Expr *selfRef,
2467+ AbstractClosureExpr *ACE) {
23642468 auto DRE = dyn_cast_or_null<DeclRefExpr>(selfRef);
2365- if (!DRE) {
2469+ if (!DRE)
23662470 return false ;
2367- }
23682471
23692472 auto selfDecl = dyn_cast_or_null<VarDecl>(DRE->getDecl ());
2370- auto ty = DRE->getType ();
2371- if (!selfDecl) {
2372- return false ;
2373- }
2374-
2375- if (isInTypePreviouslyLackingValidation (ty)) {
2376- return true ;
2377- }
2378-
2379- if (isPreviouslyPermittedWeakSelfUsage (ACE, selfDecl, ty)) {
2380- return true ;
2381- }
2382-
2383- if (isUsageAlwaysPreviouslyRejected (selfDecl)) {
2473+ if (!selfDecl)
23842474 return false ;
2385- }
2386-
2387- if (isPreviouslyPermittedStrongSelfUsage (selfDecl, ACE)) {
2388- return true ;
2389- }
2390-
2391- return false ;
2392- }
23932475
2394- bool isInTypePreviouslyLackingValidation (Type ty) {
2395- // We previously didn't validate captures at all in structs or metadata
2396- // types, so we must only warn in this case.
2397- return !ty->hasReferenceSemantics () || ty->is <MetatypeType>();
2398- }
2399-
2400- // / Checks if this usage of implicit self in a weak self closure
2401- // / was previously permitted in Swift 5.8.
2402- bool isPreviouslyPermittedWeakSelfUsage (AbstractClosureExpr *ACE,
2403- ValueDecl *selfDecl, Type ty) {
2404- auto weakSelfDecl = weakSelfCapture (ACE);
2405- if (!weakSelfDecl) {
2406- return false ;
2407- }
2408-
2409- // Implicit self was permitted for weak self captures in
2410- // non-escaping closures in Swift 5.7, so we must only warn.
2411- if (AnyFunctionRef (const_cast <AbstractClosureExpr *>(ACE))
2412- .isKnownNoEscape ()) {
2413- return true ;
2414- }
2415-
2416- // Implicit self was also permitted for weak self captures in closures
2417- // passed to @_implicitSelfCapture parameters in Swift 5.7.
2418- if (auto *CE = dyn_cast<ClosureExpr>(ACE)) {
2419- if (CE->allowsImplicitSelfCapture ())
2420- return true ;
2421- }
2422-
2423- // Invalid captures like `[weak self = somethingElse]`
2424- // were permitted in Swift 5.8, so we must only warn.
2425- if (!isSimpleSelfCapture (weakSelfDecl)) {
2426- return true ;
2427- }
2428-
2429- if (auto condStmt = parentConditionalStmt (selfDecl)) {
2430- auto isValidSelfRebinding = hasValidSelfRebinding (condStmt, Ctx);
2431-
2432- // Swfit 5.8 permitted implicit self without validating any
2433- // parent closures. If implicit self is only disallowed due to
2434- // an invalid parent, we must only warn.
2435- if (isValidSelfRebinding &&
2436- implicitSelfDisallowedDueToInvalidParent (selfDecl, ty, ACE)) {
2437- return true ;
2438- }
2439-
2440- // Swift 5.8 used `requiresLoadExpr` to validate self bindings.
2441- // If the binding is valid when only checking for a load expr,
2442- // then we must only warn.
2443- auto usesLoadExpr =
2444- condStmt->rebindsSelf (Ctx, /* requiresCaptureListRef*/ false ,
2445- /* requireLoadExpr*/ true );
2446-
2447- if (!isValidSelfRebinding && usesLoadExpr) {
2448- return true ;
2449- }
2450- }
2451-
2452- return false ;
2453- }
2454-
2455- // / Checks if this implicit self usage was always previously rejected as
2456- // / invalid, so can continue to be treated an error.
2457- bool isUsageAlwaysPreviouslyRejected (ValueDecl *selfDecl) {
2458- // If the self decl refers to a weak self unwrap condition
2459- // in some parent closure, then there is no source-compatibility
2460- // requirement to avoid an error.
2461- return hasValidSelfRebinding (parentConditionalStmt (selfDecl), Ctx);
2462- }
2463-
2464- // / Checks if this is a usage of implicit self in a strong self closure
2465- // / that was previously permitted in older versions like Swift 5.3.
2466- bool isPreviouslyPermittedStrongSelfUsage (VarDecl *selfDecl,
2467- AbstractClosureExpr *ACE) {
2468- // Implicit self was accidentially allowed in examples like this
2469- // in Swift 5.3-5.5, so check for this case and emit a warning
2470- // instead of an error:
2471- //
2472- // withEscaping { [self] in
2473- // withEscaping {
2474- // x += 1
2475- // }
2476- // }
2477- //
2478- bool isEscapingClosureWithExplicitSelfCapture = false ;
2479- if (!AnyFunctionRef (const_cast <AbstractClosureExpr *>(ACE))
2480- .isKnownNoEscape ()) {
2481- if (auto closureExpr = dyn_cast<ClosureExpr>(ACE)) {
2482- if (closureExpr->getCapturedSelfDecl ()) {
2483- isEscapingClosureWithExplicitSelfCapture = true ;
2484- }
2485- }
2476+ // If this implicit self decl is from a closure that captured self
2477+ // weakly, then we should always emit an error, since implicit self was
2478+ // only allowed starting in Swift 5.8 and later.
2479+ if (closureHasWeakSelfCapture (ACE)) {
2480+ // Implicit self was incorrectly permitted for weak self captures
2481+ // in non-escaping closures in Swift 5.7, so in that case we can
2482+ // only warn until Swift 6.
2483+ return !isClosureRequiringSelfQualification (ACE,
2484+ /* ignoreWeakSelf*/ true );
24862485 }
24872486
2488- return !selfDecl->isSelfParameter () &&
2489- !isEscapingClosureWithExplicitSelfCapture;
2487+ return !selfDecl->isSelfParameter ();
24902488 }
24912489 };
24922490
0 commit comments