@@ -2075,7 +2075,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2075
2075
// If the closure's type was inferred to be noescape, then it doesn't
2076
2076
// need qualification.
2077
2077
if (AnyFunctionRef (const_cast <AbstractClosureExpr *>(CE))
2078
- .isKnownNoEscape ())
2078
+ .isKnownNoEscape ())
2079
2079
return false ;
2080
2080
2081
2081
if (auto autoclosure = dyn_cast<AutoClosureExpr>(CE)) {
@@ -2128,122 +2128,6 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2128
2128
return Action::Continue (E);
2129
2129
}
2130
2130
2131
- // Until Swift 6, only emit a warning when we get this with an
2132
- // explicit capture, since we used to not diagnose this at all.
2133
- auto shouldOnlyWarn = [&](Expr *selfRef) {
2134
- auto DRE = dyn_cast_or_null<DeclRefExpr>(selfRef);
2135
- if (!DRE) {
2136
- return false ;
2137
- }
2138
-
2139
- auto selfDecl = dyn_cast_or_null<VarDecl>(DRE->getDecl ());
2140
- auto ty = DRE->getType ();
2141
- if (!selfDecl || !ty) {
2142
- return false ;
2143
- }
2144
-
2145
- // Implicit self was always allowed in structs and metadata types
2146
- // even if the self capture was invalid.
2147
- if (!ty->hasReferenceSemantics () || ty->is <MetatypeType>()) {
2148
- return true ;
2149
- }
2150
-
2151
- // If this implicit self decl is from a closure that captured self
2152
- // weakly, then we should always emit an error, since implicit self was
2153
- // only allowed starting in Swift 5.8 and later.
2154
- if (auto weakSelfDecl = weakSelfCapture (ACE)) {
2155
- // However implicit self was incorrectly permitted for weak self
2156
- // captures in non-escaping closures in Swift 5.7, so in that case we
2157
- // can only warn until Swift 6.
2158
- if (AnyFunctionRef (const_cast <AbstractClosureExpr *>(ACE))
2159
- .isKnownNoEscape ()) {
2160
- return true ;
2161
- }
2162
-
2163
- // If this is a capture like `[weak self = somethingElse]`,
2164
- // this unintentionally permitted implicit self in Swift 5.8 - 5.10,
2165
- // so we have to only warn until Swift 6.
2166
- if (!isSimpleSelfCapture (weakSelfDecl)) {
2167
- return true ;
2168
- }
2169
-
2170
- if (auto conditionalStmt = parentConditionalStmt (selfDecl)) {
2171
- auto isValidSelfRebinding =
2172
- hasValidSelfRebinding (conditionalStmt, ACE);
2173
-
2174
- if (isValidSelfRebinding) {
2175
- // In Swift 5.8 - 5.10 we unintentionally permitted implicit
2176
- // self without validating any parent closures. To preserve
2177
- // source compatibility, in this case we only warn until Swift 6.
2178
- if (implicitSelfDisallowedDueToInvalidParent (selfDecl, ty, ACE)) {
2179
- return true ;
2180
- }
2181
- }
2182
-
2183
- // In Swift 5.8 - 5.10 we used `requiresLoadExpr` instead
2184
- // of `requiresCaptureListRef` to validate self unwrap
2185
- // conditions. For source compatibility, if the legacy check
2186
- // succeeds but the current check fails, we should only warn
2187
- // until Swift 6.
2188
- auto legacyRebindsSelfResult =
2189
- conditionalStmt->rebindsSelf (ACE->getASTContext (),
2190
- /* requiresCaptureListRef*/ false ,
2191
- /* requiresLoadExpr*/ true );
2192
-
2193
- if (!isValidSelfRebinding && legacyRebindsSelfResult) {
2194
- return true ;
2195
- }
2196
- }
2197
- }
2198
-
2199
- // If the self decl refers to a weak self unwrapping
2200
- // condition in some parent closure, then there is no
2201
- // source-compatibility requirement to avoid an error.
2202
- if (hasValidSelfRebinding (parentConditionalStmt (selfDecl), ACE)) {
2203
- return false ;
2204
- }
2205
-
2206
- // In Swift 5 mode we didn't validate the outermost capture in
2207
- // nonescaping closures, so if only the outermost capture is invalid
2208
- // then we must only warn.
2209
- if (!isClosureRequiringSelfQualification (ACE, Ctx)) {
2210
- auto invalidParentClosure = parentClosureDisallowingImplicitSelf (selfDecl, ty, ACE);
2211
-
2212
- if (invalidParentClosure) {
2213
- auto excludingOutermostCapture = parentClosureDisallowingImplicitSelf (selfDecl, ty, ACE, /* validateOutermostCapture:*/ false );
2214
-
2215
- if (invalidParentClosure != excludingOutermostCapture) {
2216
- return true ;
2217
- }
2218
- }
2219
- }
2220
-
2221
- // Implicit self was accidentially allowed in examples like this
2222
- // in Swift 5.3-5.5, so check for this case and emit a warning
2223
- // instead of an error:
2224
- //
2225
- // withEscaping { [self] in
2226
- // withEscaping {
2227
- // x += 1
2228
- // }
2229
- // }
2230
- //
2231
- bool isEscapingClosureWithExplicitSelfCapture = false ;
2232
- if (isClosureRequiringSelfQualification (ACE, Ctx)) {
2233
- if (auto closureExpr = dyn_cast<ClosureExpr>(ACE)) {
2234
- if (closureExpr->getCapturedSelfDecl ()) {
2235
- isEscapingClosureWithExplicitSelfCapture = true ;
2236
- }
2237
- }
2238
- }
2239
-
2240
- if (!selfDecl->isSelfParameter () && !isEscapingClosureWithExplicitSelfCapture) {
2241
- return true ;
2242
- }
2243
-
2244
- return false ;
2245
- };
2246
-
2247
2131
SourceLoc memberLoc = SourceLoc ();
2248
2132
const DeclRefExpr *selfDRE = nullptr ;
2249
2133
if (auto *MRE = dyn_cast<MemberRefExpr>(E))
@@ -2255,7 +2139,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2255
2139
.diagnose (memberLoc,
2256
2140
diag::property_use_in_closure_without_explicit_self,
2257
2141
baseName.getIdentifier ())
2258
- .warnUntilSwiftVersionIf (shouldOnlyWarn (MRE->getBase ()), 6 );
2142
+ .warnUntilSwiftVersionIf (
2143
+ invalidImplicitSelfShouldOnlyWarn (MRE->getBase (), ACE), 6 );
2259
2144
}
2260
2145
2261
2146
// Handle method calls with a specific diagnostic + fixit.
@@ -2269,7 +2154,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2269
2154
.diagnose (DSCE->getLoc (),
2270
2155
diag::method_call_in_closure_without_explicit_self,
2271
2156
MethodExpr->getDecl ()->getBaseIdentifier ())
2272
- .warnUntilSwiftVersionIf (shouldOnlyWarn (DSCE->getBase ()), 6 );
2157
+ .warnUntilSwiftVersionIf (
2158
+ invalidImplicitSelfShouldOnlyWarn (DSCE->getBase (), ACE), 6 );
2273
2159
}
2274
2160
2275
2161
if (memberLoc.isValid ()) {
@@ -2285,7 +2171,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2285
2171
2286
2172
if (!selfDeclAllowsImplicitSelf (E, ACE))
2287
2173
Diags.diagnose (E->getLoc (), diag::implicit_use_of_self_in_closure)
2288
- .warnUntilSwiftVersionIf (shouldOnlyWarn (E), 6 );
2174
+ .warnUntilSwiftVersionIf (invalidImplicitSelfShouldOnlyWarn (E, ACE),
2175
+ 6 );
2289
2176
2290
2177
return Action::Continue (E);
2291
2178
}
@@ -2444,9 +2331,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2444
2331
// insert 'self,'. If it wasn't a valid entry, then we will at least not
2445
2332
// be introducing any new errors/warnings...
2446
2333
const auto locAfterBracket = brackets.Start .getAdvancedLoc (1 );
2447
- const auto nextAfterBracket =
2448
- Lexer::getTokenAtLocation (Ctx.SourceMgr , locAfterBracket,
2449
- CommentRetentionMode::None);
2334
+ const auto nextAfterBracket = Lexer::getTokenAtLocation (
2335
+ Ctx.SourceMgr , locAfterBracket, CommentRetentionMode::None);
2450
2336
if (nextAfterBracket.getLoc () != brackets.End )
2451
2337
diag.fixItInsertAfter (brackets.Start , " self, " );
2452
2338
else
@@ -2474,6 +2360,133 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
2474
2360
2475
2361
diag.fixItInsertAfter (closureExpr->getLoc (), " [self] in" + trailing);
2476
2362
}
2363
+
2364
+ // / Whether or not this invalid usage of implicit self should be a warning
2365
+ // / in Swift 5 mode, to preserve source compatibility.
2366
+ bool invalidImplicitSelfShouldOnlyWarn (Expr *selfRef,
2367
+ AbstractClosureExpr *ACE) {
2368
+ auto DRE = dyn_cast_or_null<DeclRefExpr>(selfRef);
2369
+ if (!DRE) {
2370
+ return false ;
2371
+ }
2372
+
2373
+ auto selfDecl = dyn_cast_or_null<VarDecl>(DRE->getDecl ());
2374
+ auto ty = DRE->getType ();
2375
+ if (!selfDecl) {
2376
+ return false ;
2377
+ }
2378
+
2379
+ if (isInTypePreviouslyLackingValidation (ty)) {
2380
+ return true ;
2381
+ }
2382
+
2383
+ if (isPreviouslyPermittedWeakSelfUsage (ACE, selfDecl, ty)) {
2384
+ return true ;
2385
+ }
2386
+
2387
+ if (isUsageAlwaysPreviouslyRejected (selfDecl, ACE)) {
2388
+ return false ;
2389
+ }
2390
+
2391
+ if (isPreviouslyPermittedStrongSelfUsage (selfDecl, ACE)) {
2392
+ return true ;
2393
+ }
2394
+
2395
+ return false ;
2396
+ }
2397
+
2398
+ bool isInTypePreviouslyLackingValidation (Type ty) {
2399
+ // We previously didn't validate captures at all in structs or metadata
2400
+ // types, so we must only warn in this case.
2401
+ return !ty->hasReferenceSemantics () || ty->is <MetatypeType>();
2402
+ }
2403
+
2404
+ // / Checks if this usage of implicit self in a weak self closure
2405
+ // / was previously permitted in Swift 5.8.
2406
+ bool isPreviouslyPermittedWeakSelfUsage (AbstractClosureExpr *ACE,
2407
+ ValueDecl *selfDecl, Type ty) {
2408
+ auto weakSelfDecl = weakSelfCapture (ACE);
2409
+ if (!weakSelfDecl) {
2410
+ return false ;
2411
+ }
2412
+
2413
+ // Implicit self was permitted for weak self captures in
2414
+ // non-escaping closures in Swift 5.7, so we must only warn.
2415
+ if (AnyFunctionRef (const_cast <AbstractClosureExpr *>(ACE))
2416
+ .isKnownNoEscape ()) {
2417
+ return true ;
2418
+ }
2419
+
2420
+ // Invalid captures like `[weak self = somethingElse]`
2421
+ // were permitted in Swift 5.8, so we must only warn.
2422
+ if (!isSimpleSelfCapture (weakSelfDecl)) {
2423
+ return true ;
2424
+ }
2425
+
2426
+ if (auto condStmt = parentConditionalStmt (selfDecl)) {
2427
+ auto isValidSelfRebinding = hasValidSelfRebinding (condStmt, ACE);
2428
+
2429
+ // Swfit 5.8 permitted implicit self without validating any
2430
+ // parent closures. If implicit self is only disallowed due to
2431
+ // an invalid parent, we must only warn.
2432
+ if (isValidSelfRebinding &&
2433
+ implicitSelfDisallowedDueToInvalidParent (selfDecl, ty, ACE)) {
2434
+ return true ;
2435
+ }
2436
+
2437
+ // Swift 5.8 used `requiresLoadExpr` to validate self bindings.
2438
+ // If the binding is valid when only checking for a load expr,
2439
+ // then we must only warn.
2440
+ auto usesLoadExpr =
2441
+ condStmt->rebindsSelf (ACE->getASTContext (),
2442
+ /* requiresCaptureListRef*/ false ,
2443
+ /* requireLoadExpr*/ true );
2444
+
2445
+ if (!isValidSelfRebinding && usesLoadExpr) {
2446
+ return true ;
2447
+ }
2448
+ }
2449
+
2450
+ return false ;
2451
+ }
2452
+
2453
+ // / Checks if this implicit self usage was always previously rejected as
2454
+ // / invalid, so can continue to be treated an error.
2455
+ bool isUsageAlwaysPreviouslyRejected (ValueDecl *selfDecl,
2456
+ AbstractClosureExpr *ACE) {
2457
+ // If the self decl refers to a weak self unwrap condition
2458
+ // in some parent closure, then there is no source-compatibility
2459
+ // requirement to avoid an error.
2460
+ return hasValidSelfRebinding (parentConditionalStmt (selfDecl), ACE);
2461
+ }
2462
+
2463
+ // / Checks if this is a usage of implicit self in a strong self closure
2464
+ // / that was previously permitted in older versions like Swift 5.3.
2465
+ bool isPreviouslyPermittedStrongSelfUsage (VarDecl *selfDecl,
2466
+ AbstractClosureExpr *ACE) {
2467
+ // Implicit self was accidentially allowed in examples like this
2468
+ // in Swift 5.3-5.5, so check for this case and emit a warning
2469
+ // instead of an error:
2470
+ //
2471
+ // withEscaping { [self] in
2472
+ // withEscaping {
2473
+ // x += 1
2474
+ // }
2475
+ // }
2476
+ //
2477
+ bool isEscapingClosureWithExplicitSelfCapture = false ;
2478
+ if (!AnyFunctionRef (const_cast <AbstractClosureExpr *>(ACE))
2479
+ .isKnownNoEscape ()) {
2480
+ if (auto closureExpr = dyn_cast<ClosureExpr>(ACE)) {
2481
+ if (closureExpr->getCapturedSelfDecl ()) {
2482
+ isEscapingClosureWithExplicitSelfCapture = true ;
2483
+ }
2484
+ }
2485
+ }
2486
+
2487
+ return !selfDecl->isSelfParameter () &&
2488
+ !isEscapingClosureWithExplicitSelfCapture;
2489
+ }
2477
2490
};
2478
2491
2479
2492
auto &ctx = DC->getASTContext ();
0 commit comments