@@ -2075,7 +2075,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
20752075 // If the closure's type was inferred to be noescape, then it doesn't
20762076 // need qualification.
20772077 if (AnyFunctionRef (const_cast <AbstractClosureExpr *>(CE))
2078- .isKnownNoEscape ())
2078+ .isKnownNoEscape ())
20792079 return false ;
20802080
20812081 if (auto autoclosure = dyn_cast<AutoClosureExpr>(CE)) {
@@ -2128,122 +2128,6 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
21282128 return Action::Continue (E);
21292129 }
21302130
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-
22472131 SourceLoc memberLoc = SourceLoc ();
22482132 const DeclRefExpr *selfDRE = nullptr ;
22492133 if (auto *MRE = dyn_cast<MemberRefExpr>(E))
@@ -2255,7 +2139,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
22552139 .diagnose (memberLoc,
22562140 diag::property_use_in_closure_without_explicit_self,
22572141 baseName.getIdentifier ())
2258- .warnUntilSwiftVersionIf (shouldOnlyWarn (MRE->getBase ()), 6 );
2142+ .warnUntilSwiftVersionIf (
2143+ invalidImplicitSelfShouldOnlyWarn (MRE->getBase (), ACE), 6 );
22592144 }
22602145
22612146 // Handle method calls with a specific diagnostic + fixit.
@@ -2269,7 +2154,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
22692154 .diagnose (DSCE->getLoc (),
22702155 diag::method_call_in_closure_without_explicit_self,
22712156 MethodExpr->getDecl ()->getBaseIdentifier ())
2272- .warnUntilSwiftVersionIf (shouldOnlyWarn (DSCE->getBase ()), 6 );
2157+ .warnUntilSwiftVersionIf (
2158+ invalidImplicitSelfShouldOnlyWarn (DSCE->getBase (), ACE), 6 );
22732159 }
22742160
22752161 if (memberLoc.isValid ()) {
@@ -2285,7 +2171,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
22852171
22862172 if (!selfDeclAllowsImplicitSelf (E, ACE))
22872173 Diags.diagnose (E->getLoc (), diag::implicit_use_of_self_in_closure)
2288- .warnUntilSwiftVersionIf (shouldOnlyWarn (E), 6 );
2174+ .warnUntilSwiftVersionIf (invalidImplicitSelfShouldOnlyWarn (E, ACE),
2175+ 6 );
22892176
22902177 return Action::Continue (E);
22912178 }
@@ -2444,9 +2331,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
24442331 // insert 'self,'. If it wasn't a valid entry, then we will at least not
24452332 // be introducing any new errors/warnings...
24462333 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);
24502336 if (nextAfterBracket.getLoc () != brackets.End )
24512337 diag.fixItInsertAfter (brackets.Start , " self, " );
24522338 else
@@ -2474,6 +2360,133 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
24742360
24752361 diag.fixItInsertAfter (closureExpr->getLoc (), " [self] in" + trailing);
24762362 }
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+ }
24772490 };
24782491
24792492 auto &ctx = DC->getASTContext ();
0 commit comments