@@ -1715,6 +1715,91 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1715
1715
Closures.push_back (ACE);
1716
1716
}
1717
1717
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
+
1718
1803
// / Whether or not implicit self is allowed for self decl
1719
1804
static bool
1720
1805
selfDeclAllowsImplicitSelf (Expr *E, const AbstractClosureExpr *inClosure) {
@@ -1731,6 +1816,11 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1731
1816
if (!ty)
1732
1817
return true ;
1733
1818
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
+
1734
1824
return selfDeclAllowsImplicitSelf (DRE->getDecl (), ty, inClosure,
1735
1825
/* validateParentClosures:*/ true ,
1736
1826
/* validateSelfRebindings:*/ true );
@@ -2063,8 +2153,9 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2063
2153
// / Return true if this is a closure expression that will require explicit
2064
2154
// / use or capture of "self." for qualification of member references.
2065
2155
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)) {
2068
2159
return true ;
2069
2160
}
2070
2161
@@ -2110,9 +2201,20 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2110
2201
2111
2202
bool shouldWalkCaptureInitializerExpressions () override { return true ; }
2112
2203
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
+
2113
2214
PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
2114
2215
if (auto *CE = dyn_cast<AbstractClosureExpr>(E)) {
2115
- Closures.push_back (CE);
2216
+ if (shouldRecordClosure (CE))
2217
+ Closures.push_back (CE);
2116
2218
}
2117
2219
2118
2220
// If we aren't in a closure, no diagnostics will be produced.
@@ -2144,7 +2246,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2144
2246
diag::property_use_in_closure_without_explicit_self,
2145
2247
baseName.getIdentifier ())
2146
2248
.warnUntilSwiftVersionIf (
2147
- invalidImplicitSelfShouldOnlyWarn (MRE->getBase (), ACE), 6 );
2249
+ invalidImplicitSelfShouldOnlyWarn510 (MRE->getBase (), ACE), 6 );
2148
2250
}
2149
2251
2150
2252
// Handle method calls with a specific diagnostic + fixit.
@@ -2159,12 +2261,13 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2159
2261
diag::method_call_in_closure_without_explicit_self,
2160
2262
MethodExpr->getDecl ()->getBaseIdentifier ())
2161
2263
.warnUntilSwiftVersionIf (
2162
- invalidImplicitSelfShouldOnlyWarn (DSCE->getBase (), ACE), 6 );
2264
+ invalidImplicitSelfShouldOnlyWarn510 (DSCE->getBase (), ACE),
2265
+ 6 );
2163
2266
}
2164
2267
2165
2268
if (memberLoc.isValid ()) {
2166
2269
const AbstractClosureExpr *parentDisallowingImplicitSelf = nullptr ;
2167
- if (selfDRE && selfDRE->getDecl ()) {
2270
+ if (Ctx. isSwiftVersionAtLeast ( 6 ) && selfDRE && selfDRE->getDecl ()) {
2168
2271
parentDisallowingImplicitSelf = parentClosureDisallowingImplicitSelf (
2169
2272
selfDRE->getDecl (), selfDRE->getType (), ACE);
2170
2273
}
@@ -2173,11 +2276,11 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2173
2276
return Action::SkipNode (E);
2174
2277
}
2175
2278
2176
- if (!selfDeclAllowsImplicitSelf (E, ACE))
2279
+ if (!selfDeclAllowsImplicitSelf (E, ACE)) {
2177
2280
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
+ }
2181
2284
return Action::Continue (E);
2182
2285
}
2183
2286
@@ -2187,9 +2290,10 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2187
2290
return Action::Continue (E);
2188
2291
}
2189
2292
2190
- assert (Closures.size () > 0 );
2191
- Closures.pop_back ();
2192
-
2293
+ if (shouldRecordClosure (ACE)) {
2294
+ assert (Closures.size () > 0 );
2295
+ Closures.pop_back ();
2296
+ }
2193
2297
return Action::Continue (E);
2194
2298
}
2195
2299
@@ -2367,132 +2471,28 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2367
2471
2368
2472
// / Whether or not this invalid usage of implicit self should be a warning
2369
2473
// / in Swift 5 mode, to preserve source compatibility.
2370
- bool invalidImplicitSelfShouldOnlyWarn (Expr *selfRef,
2371
- AbstractClosureExpr *ACE) {
2474
+ bool invalidImplicitSelfShouldOnlyWarn510 (Expr *selfRef,
2475
+ AbstractClosureExpr *ACE) {
2372
2476
auto DRE = dyn_cast_or_null<DeclRefExpr>(selfRef);
2373
- if (!DRE) {
2477
+ if (!DRE)
2374
2478
return false ;
2375
- }
2376
2479
2377
2480
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)
2392
2482
return false ;
2393
- }
2394
-
2395
- if (isPreviouslyPermittedStrongSelfUsage (selfDecl, ACE)) {
2396
- return true ;
2397
- }
2398
-
2399
- return false ;
2400
- }
2401
2483
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 );
2492
2493
}
2493
2494
2494
- return !selfDecl->isSelfParameter () &&
2495
- !isEscapingClosureWithExplicitSelfCapture;
2495
+ return !selfDecl->isSelfParameter ();
2496
2496
}
2497
2497
};
2498
2498
0 commit comments